首页

原生代码之实现轮播图(左右翻页,定时翻页,指定翻页)

前端达人

首先在写代码之前我们需要理清如何穿插图片呢?



可以让所有图片都float:left,用一个大盒子装进所有图片,在用一个小盒子显示图片,溢出图片就hidden,之后以每张图片的宽度来scrollLeft.

可以给每张图片一个name/id,用循环遍历所有图片

可以用float:left,但是除了我要显示的图片外,其他图片都hidden,之后每当我需要某张图片时,我就把它制定到某位置



在这里,我将用第二种方法,因为它很直观明了,我要哪张图片我就调哪张图片。

HTML部分:在div里面我装了一张图片,name:0, 这是为了在刚打开的时候,我们的页面是有东西的而不是一片空白。其他部分都好理解,不理解的可在下方评论。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>轮播图</title>
        <link rel="stylesheet" href="轮播图.css" />
        <script src="轮播图.js">
        </script>
    </head>

    <body>
        <header>
            <div id="oImg">
                <!-- 轮流播放图片 -->
                <img id="insert" src="img/轮1.jpg" name="0"/>
            </div>
            <!-- 左右切换图片 -->
            <p id="left" οnclick="goBack()"></p>
            <p id="right" οnclick="goForward()"></p>

            <ul id="nav">
                <!-- 指定某张图片 -->
                <li id="1" οnclick="move(this)">1</li>
                <li id="2" οnclick="move(this)">2</li>
                <li id="3" οnclick="move(this)">3</li>
                <li id="4" οnclick="move(this)">4</li>
                <li id="5" οnclick="move(this)">5</li>
            </ul>
        </header>

    </body>

</html>

CSS:
* {
    margin: 0 auto;
    padding: 0 auto;
}

header {
    width: 100%;
    height: 680px;
    position: relative;

}

img {
    width: 100%;
    height: 680px; 
}   

#nav { 
    position: absolute;
    bottom: 5px;
    left: 30%;
}

#nav li {
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background: #ccc;
    font-size: 24px;
    border-radius: 9px;
    color: darkslategrey;
    font-family: 'Times New Roman', Times, serif;
    margin: 0 25px;
    float: left;
    cursor: pointer;
    list-style: none;
}

#nav li:hover {
    background: peru;
}

#left {
    width: 25px;
    height: 24px;
    left: 0;
    top: 50%;
    cursor: pointer;
    position: absolute;
    background: url(img/fx1.png);
}

#right {
    width: 25px;
    height: 24px;
    right: 0;
    top: 50%;
    cursor: pointer;
    position: absolute;
    background: url(img/fx2.png);
}
之后我们来看重中之重JS部分
JavaScript:
// 五张图片的url
var oImg1 = "img/轮1.jpg";
var oImg2 = "img/轮2.jpg";
var oImg3 = "img/轮3.jpg";
var oImg4 = "img/轮4.jpg";
var oImg5 = "img/轮5.jpg";
// 把5张图片存入一个数组
var arr = [oImg1, oImg2, oImg3, oImg4, oImg5];

window.onload = function() {
    //刚加载时第一张图片1号背景颜色
    document.getElementById("1").style.background = "peru";  
    run()

}

//轮播
function run() { 
    timer = setInterval(function() {
        //随机点数字时能接着变化 
        var pic = document.getElementById("insert").name;
        var shade = document.getElementById("insert");  

        //如果为最后一张图片则重新循环
        if (pic == 4) {
            pic = -1;
        }

        //点一个数字该数字背景颜色变化其余的不变
        var aLi = document.getElementsByTagName("li");
        for (var j = 0; j < aLi.length; j++) {
            aLi[j].style.backgroundColor = "#CCCCCC";
        } 

        var i = parseInt(pic);   

        document.getElementById("insert").src = arr[i + 1]; 

        document.getElementById("insert").name = i + 1; 

        //数字随图片变化
        switch (i) {
            case 0:
                var temp = '2';
                break;
            case 1:
                var temp = '3';
                break;
            case 2:
                var temp = '4';
                break;
            case 3:
                var temp = '5';
                break;
            case -1:
                var temp = '1';
                break;
        }
        document.getElementById(temp).style.background = "peru"   

    }, 5000)
}

//右箭头 
function goForward() {
    var temp = document.getElementById("insert").name;
    var oBox = document.getElementById("insert"); 
    var aLi = document.getElementsByTagName("li");
    // 数字跟着图片一起变
    for (var i = 0; i < aLi.length; i++) {
        aLi[i].style.backgroundColor = "#CCCCCC";
    }

    switch (temp) {
        case "0":
            var n = '2';
            break;
        case "1":
            var n = '3';
            break;
        case "2":
            var n = '4';
            break;
        case "3":
            var n = '5';
            break;
        case "4":
            var n = '1';
            break;
    }

    document.getElementById(n).style.background = "peru"
    // 向右移动图片
    for (var j = 0; j < arr.length; j++) {
        if (j < 4) {
            if (temp == j) {
                oBox.src = arr[j + 1]; 
            }
        } else {
            if (temp == 4) {
                oBox.src = arr[0]; 
            }
        }
    } 
    // 轮到最后一张图片时返回第一张
    if (temp < 4) {
        oBox.name = parseInt(temp) + 1;
    } else {
        oBox.name = 0;
    }
}

//左箭头
function goBack() {
    var temp = document.getElementById("insert").name;
    var oBox = document.getElementById("insert")
    var aLi = document.getElementsByTagName("li");
    // 图片移动时数字也跟着变
    for (var i = 0; i < aLi.length; i++) {
        aLi[i].style.backgroundColor = "#CCCCCC";
    }

    switch (temp) {
        case "0":
            var n = '5';
            break;
        case "1":
            var n = '1';
            break;
        case "2":
            var n = '2';
            break;
        case "3":
            var n = '3';
            break;
        case "4":
            var n = '4';
            break;
    }

    document.getElementById(n).style.background = "peru"
    // 向左移动图片 

    for (var j = 0; j < arr.length; j++) {
        if (j > 0) {
            if (temp == j) {
                oBox.src = arr[j - 1];
            }
        } else {
            if (temp == 0) {
                oBox.src = arr[4];
            }
        }
    }
    // 轮到第一张图片时返回最后一张
    if (temp > 0) {
        oBox.name = parseInt(temp) - 1;
    } else {
        oBox.name = 4;
    }
}

//指定图片
function move(num) { 
    var oBox = document.getElementById("insert");
    var temp = document.getElementById("insert").name;
    var aLi = document.getElementsByTagName("li");
    for (var i = 0; i < aLi.length; i++) {
        aLi[i].style.backgroundColor = "#CCCCCC";
    }

    document.getElementById(num.innerHTML).style.background = "peru"

    switch (num.innerHTML) {
        case "1":
            oBox.src = arr[0];
            oBox.name = 0;
            break;
        case "2":
            oBox.src = arr[1];
            oBox.name = 1;
            break;
        case "3":
            oBox.src = arr[2];
            oBox.name = 2;
            break;
        case "4":
            oBox.src = arr[3];
            oBox.name = 3;
            break;
        case "5":
            oBox.src = arr[4];
            oBox.name = 4;
            break;
    }
}
JavaScript部分我写的很详细,仔细看的话是可以看懂的,主要分3个重要部分:

用src来调用每张图片并给每张图片一个name,这样方便后面的重复使用
为下方的数字按钮匹配图片,点击1跳到第1张图片,点击2跳到第2张图片…因为我把所有的图片都存在了一个数组里,所以在匹配的时候要注意数组0位置才是数字1指定的图片
可以来回翻页,当到达最后一张图片时,我再点击下一张图片又能返回到第一张图片了,亦或者当我点击到第一张图片时,再上一张图片又回到第五张图片了
效果如下:

点击查看原图

点击查看原图

大家有问题可以在下方评论哦,看到了会及时回复哒!


————————————————
版权声明:本文为CSDN博主「weixin_43964414」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43964414/article/details/104844041

CSS学习笔记(一)——CSS基础&选择器合集

前端达人

CSS介绍

整理完了HTML的笔记,接下来就是CSS了。我们可以使用HTML构建稳定的结构基础,而页面的风格样式控制则交给CSS来完成。网页的样式包括各种元素的颜色、大小、线形、间距等等,这对于设计或维护一个数据较多的网站来说,工作量是巨大的。好在可以使用CSS来控制这些样式,这将大大提高网页设计和维护的效率,并且使网页的整体风格很容易做到统一。



CSS概述

CSS是英文Cascading Style Sheet的缩写,中文译为层叠样式表,也有人翻译为级联样式表,简称样式表。它是一种用来定义网页外观样式的技术,在网页中引入CSS规则,可以快捷地对页面进行布局设计,可以的控制HTML标记对象的宽度、高度、位置、字体、背景等外观效果。

CSS是一种标识性语言,不仅可以有效的控制网页的样式,更重要的是实现了网页内容与样式的分离,并允许将CSS规则单独存放于一个文档中, CSS文件的扩展名为“css”。



CSS3

CSS3标准早在1995年就开始制订, 2001年提上W3C研究议程,但是,10年来CSS3可以说是基本上没有什么很大的变化,一直到2011年6月才发布了全新版本的CSS3,目前,许多浏览器都广泛支持CSS3。

CSS3是CSS技术的一个升级版本,CSS3语言将CSS划分为更小的模块,在朝着模块化的方向发展。以前的版本是一个比较庞大而且比较复杂模块,所以,把它分解成为一个个小的简单的模块,同时也加入了更多新的模块。在CSS3中有字体、颜色、布局、背景、定位、边框、多列、动画、用户界面等等多个模块。



CSS的基本用法

CSS的使用规则由两部分组成:选择器和一条或多条声明。其基本基本语法如下:

 选择器{ 属性1:; 属性2:; …
            属性n:; }

CSS的使用规则由两部分组成:选择器和一条或多条声明。其基本基本语法如下:

 选择器{ 属性1:; 属性2:; 

属性n:; }

20200313203814532.png

CSS属性

CSS的属性按照相关功能进行了分组,包含了字体、文本、背景、列表、动画等多个分组,这些属性的具体使用方法和示例将会在后续中提到。



在HTML文档中使用CSS的方法

根据CSS在HTML文档中的使用方法和作用范围不同,CSS样式表的使用方法分为三大类:行内样式、内部样式表和外部样式表,而外部样式表又可分为链入外部样式表和导入外部样式表。本节我们从四个分类来认识在HTML中使用CSS的方法。



行内样式

内部样式表

外部样式表

链入外部样式表

导入外部样式表

行内样式

行内样式(inline style),也叫内联样式,它是CSS四种使用方法中最为直接的一种,它的实现借用HTML元素的全局属性style,把CSS代码直接写入其中即可。

严格意义上行内样式是一种不严谨的使用方式,它不需要选择器,这种方式下CSS代码和HTML代码混合在一起,因此不推荐使用行内样式。行内样式的基本语法如下:

  <标记 style="属性:值; 属性:值; …">


内部样式表

当单个文档需要特殊的样式时,应该使用内部样式表。内部样式表是将样式放在页面的head区里,这样定义的样式就应用到本页面中了,内部样式表使用style标记进行声明,是较为常用的一种使用方法。其基本语法如下:

<head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            选择器1{属性:值;…}
            选择器2{属性:值;…}
            ……
            选择器n{属性:值;…}
        </style>
    </head>


style标记定义HTML文档的样式信息,规定的是 HTML 元素如何在浏览器中呈现,其中type用来指定元素中的内容类型。

链入外部样式表
当为了保证站点的风格统一,或当定义样式内容较多,且需要多个页面共享样式时,可使用外部样式表。链入外部样式表是把样式表保存为一个外部样式表文件,然后在页面中用link标记链接到这个样式表文件,link标记放在页面的head区内。其基本语法为:

<head>
        <meta charset="utf-8" />
        <title></title>
        <link href="样式表路径" rel="stylesheet" type="text/css" />
    </head>
其中:
href:指出样式表存放的路径。
rel:用来定义链接的文件与HTML之间的关系, rel="stylesheet"是指在页面中使用这个外部的样式表。
type属性用于指定文件类型,“text/css”指文件的类型是样式表文本。

导入外部样式表
导入外部样式表是指在HTML文件头部的style元素里导入一个外部样式表,导入外部样式表采用import方式。导入外部样式表和链入样式表的方法很相似,但导入外部样式表的样式实质上相当于存在网页内部。其基本语法为:
————————————————
版权声明:本文为CSDN博主「狗狗狗狗狗乐啊」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44122062/article/details/104848745

<head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            @import url("样式表路径");
        </style>
    </head>
其中:
href:指出样式表存放的路径。
rel:用来定义链接的文件与HTML之间的关系, rel="stylesheet"是指在页面中使用这个外部的样式表。
type属性用于指定文件类型,“text/css”指文件的类型是样式表文本。

导入外部样式表
导入外部样式表是指在HTML文件头部的style元素里导入一个外部样式表,导入外部样式表采用import方式。导入外部样式表和链入样式表的方法很相似,但导入外部样式表的样式实质上相当于存在网页内部。其基本语法为:

  <head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            @import url("样式表路径");
        </style>
    </head>

结语

记录仓促,遗漏之处日后补充,如有错误或不足之处,还望指正

————————————————
版权声明:本文为CSDN博主「狗狗狗狗狗乐啊」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44122062/article/details/104848745


Vue移动端项目优化过程

前端达人

文章目录

前言

一、白屏时间过长分析

二、针对性优化

针对animate.css

针对mint-ui的优化

针对图片的优化

三、webpack打包优化与分析

webpack-bundle-analyzer打包分析

打包优化

四、优化后线上测试速度提升

五、优化总结

前言

最近在做项目时,测试提出了在App端的H5项目入口加载时间过长,白屏等待过久,需要优化的问题,于是着手开始分析:



项目技术栈:基于Vue全家桶做的一个移动端类似WebApp的项目,使用到的第三方库有:mint-ui, echarts,momentjs。

项目痛点:白屏时间过长

一、白屏时间过长分析

 通过访问线上环境,结合Chrome devtool中Network和Performance功能可以具体分析整个白屏的耗时主要在哪一块儿

Network耗时记录:

点击查看原图

Performance性能面板

点击查看原图

通过上面两张图分析,从浏览器发起请求到解析HTML完成这一过程中:
animate.css, mini-ui.css的请求耗时最长。
图片过大耗时。
二、针对性优化
针对animate.css
animate.css由于使用的是第三方CDN(国外服务器)所有请求时间相对较长,所以如果必须要用animate.css那么可以下载下来作为本地资源,也可以使用国内CDN,或者不用animate.css,而是针对使用到的几个CSS动画,直接自己造轮子
针对mint-ui的优化
由于mint-ui在原项目中使用的是全局引用的方式,这才导致打包资源过大,css单独请求耗时过长的问题,所以主要解决方案是按需引入mint-ui,借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

安装babel-plugin-component, 若已安装可忽略
修改 .babelrc (重点在plugins中):


{
  "presets": [
    ["env", { "modules": false }],
    "stage-2"
  ],
  "plugins": ["transform-runtime",["component", [
      {
          "libraryName": "mint-ui",
          "style": true
      }
  ]]],
  "comments": false,
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": [ "istanbul" ]
    }
  }
}


在main.js中引用使用到的插件


import Vue from 'vue'
import { Button, Cell } from 'mint-ui'
import 'mint-ui/lib/style.min.css'  // 引用CSS
import App from './App.vue'

Vue.component(Button.name, Button)
Vue.component(Cell.name, Cell)
/* 或写为
 * Vue.use(Button)
 * Vue.use(Cell)
 */

new Vue({
  el: '#app',
  components: { App }
})


在使用的组件中改为按需引用组件


import Vue from 'vue'
 var Popup = Vue.component('mt-popup')
 var Swipe = Vue.component('mt-swipe')
 var SwipeItem = Vue.component('mt-swipe-item')
 export default {
    name:'my-component',
    components:{
     Popup,
     Swipe,
     SwipeItem
    }
}

此按需引入方案也同样适用于其他第三方UI组件库



针对图片的优化

图片小图通过webpack可以直接转为base64,而大图可以通过压缩或者换格式的方式来优化,这里推荐一个好用的图片压缩工具,工具:tinyPNG,如下是图片转换前后对比


点击查看原图


三、webpack打包优化与分析

在完成了上述优化以后,下面着重关注下webpack打包后生成的文件大小,看还有没有可以优化的余地。由于项目中已经通过路由按需加载的方式来做了功能拆分,所以通过webpack打包后生成了很多分散的js文件,如下图:


20200313153537713.png

通过上图分析可以知道打包后有几个文件相对较大,vendor.js都知道是第三方库文件打包形成,之前通过mint-ui按需加载会有一定的变化,后面记录。这里着重看另两个带hash的js文件,这里并看不出来它为什么这么大,所以这里需要用到webpack打包分析工具来做进一步的打包文件分析:webpack-bundle-analyzer

webpack-bundle-analyzer打包分析

它的作用如下图,即在打包后生成打包文件大小分析图,方便我们更加直观的看到文件大小和引用情况

点击查看原图



  • 这里先介绍下webpack-bundle-analyzer的简单使用
  1. 安装
npm intall -D webpack-bundle-analyzer
  1. 修改webpack.pro.conf.js. (这里由于只是用于生产打包分析且是通过vue-cli生成的项目框架)
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
    // ...
    plugins:[
        new BundleAnalyzerPlugin()
    ]
}

运行npm run build,(webpack默认会在打包完成时生成分析图)



版权声明:本文为CSDN博主「Sophie_U」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Sophie_U/article/details/104840167

数据类型的转化(JavaScript)

前端达人

数据类型的转化(JavaScript)—自动转化和强制转化

这一周,我来分享一下在JavaScript中的数据类型转化。

首先我们要知道在JavaScript中的数据类型有什么?在这里我就不详细介绍了,帮你总结好了。

1.布尔类型-----Boolean---isNaN()
    用来判断一个变量是否为非数字的类型,是数字返回false,不是数字返回true。
 2.数值类型-----Number
    存储时,是按照二进制数值存储,输出时,默认都是按照十进制数值输出。
    在JavaScript中二进制前加0b/0B,八进制前面加0 ,十六进制前面加0x。
    如果需要按照原始进制数值输出,用格式为:
            变量名称.toString(进制) ;
    注意的是:S必须大写,将数值转化为字符串形式输出
    如:console.log( a.toString(2) );将a转换成2进制的形式输出。
 3.字符串类型-----String
    JavaScript可以用单引号嵌套双引号, 或者用双引号嵌套单引号(外双内单,外单内双)
    字符串是由若干字符组成的,这些字符的数量就是字符串的长度。
    通过字符串的length属性可以获取整个字符串的长度。
        例子:var str = 'my name is xiaoming';
                  console.log(str.length);
          输出的结果是19。可以知道空格也代表一个字符。
 4.undefined
    表示没有数值-----应该有数值,但是现在没有数值
 5.null
    表示数值为空-----表示有数值,但是数值是“空”
上面就是数据类型的五种形式。那么它是如何转化呢?听我详细给你讲解。

在 JavaScript 程序中 , 变量中存储的数据类型没有限制,也就是在变量中可以存储任何符合JavaScript语法规范的数据类型。但是在 JavaScript 程序的执行过程中,往往需要变量中存储的数值是某种特定的数据类型,别的数据类型不行,此时就需要进行数据类型的转化。
————————————————
版权声明:本文为CSDN博主「什什么都绘」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39406353/article/details/104864224上面就是数据类型的五种形式。那么它是如何转化呢?听我详细给你讲解。

在 JavaScript 程序中 , 变量中存储的数据类型没有限制,也就是在变量中可以存储任何符合JavaScript语法规范的数据类型。但是在 JavaScript 程序的执行过程中,往往需要变量中存储的数值是某种特定的数据类型,别的数据类型不行,此时就需要进行数据类型的转化。
JavaScript中数据类型的转化,分为自动转化和强制转化:
        自动转化是计算机程序,自动完成的转化。
        强制转化是程序员,强行完成的转化
1.布尔类型的自动转化:
 在 执行 if 判断时 ,其他数据类型会自动转化为布尔类型
         其他类型转化为布尔类型的原则
   0   ''   undefined   null  NaN  这五种情况转化为false
          特别提醒 0.0  0.00000  都算是0 
 其他的所有都会转化为 true
2.字符串的自动转化:
  执行字符串拼接, +号的两侧,应该都是字符串类型,会将其他数据类型转化为字符串类型
        转化原则:
            //基本数据类型 / 简单数据类型------将数据数值直接转化为字符串 , 然后执行拼接操作
         布尔值 true  ---> 字符串 'true'
         布尔值 false ---> 字符串 'fasle'
         undefined ---> 字符串 'undefined'
         unll ---> 字符串 'null'
         数值 ---> 将数值解析转化为'对应的纯数字的字符串'
            // 引用数据类型 / 复杂数据类型
         数组 ---> 将 [] 中的内容,转化为字符串的形式,执行拼接操作
         对象 ---> 任何对象,任何内容,都会转化为 [object Object] 固定的内容形式,执行拼接操作
         函数 ---> 将所有的程序代码,转化为字符串,执行拼接操作
3.数值的自动转化:
在执行运算时,会触发数据类型的自动转化。
 转化原则:
    布尔类型 : true  --->  1         
               false --->  0
    undefined : 转化为 NaN 
    null : 转化为 0
    字符串 : 
        如果整个字符串,是纯数字字符串,或者符合科学计数法 ---> 转化为对应的数值
       如果字符串内有不符合数字规范的内容 ---> 转化为 NaN 
    数组,对象,函数:
      如果是+加号执行的是字符串拼接效果,按照这些数据类型转化为字符串的原则来转化
      如果是其他形式的运算 执行结果都是 NaN
4.布尔类型的强制转化:
 
  布尔类型的强制转化就是使用JavaScript中定义好的 方法/函数 Boolean( 数据/变量 )
  Boolean() 这个方法 不会改变 变量中存储的原始数值
   转化原则与自动转化原则相同
     0   ''   undefined  null  NaN --------> false 
     其他数据,都转化为true
5.字符串类型的强制转化:
  
 方法1,变量.toString(进制类型)
         将数值强制转化为字符串,并且可以设定转化的进制,.toString() 之前,不能直接写数值,必须是写成变量的形式
         进制常用的数值是 2 8 16 ,可以设定的范围是 2 - 36 进制  
 方法2,String( 变量 / 数据 )
         将变量或者数据,转化为字符串,原则按照自动转化的原则来执行,不会改变变量中存储的原始数值
         但是在字符串拼接时,会将其他数据类型自动转化为字符串
 6.数字类型的强制转化:
 
方法1 , Number(变量/数值) 
         console.log( Number(true) );   // 1
         console.log( Number(false) );  // 0
         console.log( Number(null) );   // 0
         console.log( Number(undefined) );   // NaN
         console.log( Number('100') );       // 对应的数值
         console.log( Number('100.123') );   // 对应的数值
         console.log( Number('2e4') );       // 对应的数值
         console.log( Number('123abc') );    // NaN
         console.log( Number( [1,2,3,4,5] ) );                           // NaN
         console.log( Number( {name:'zhangsan'} ) );                     // NaN
         console.log( Number( function fun(){console.log('abc')} ) );    // NaN
 将其他类型强制转化为数值类型,转化原则与自动转化选择相同

 方法2, parseInt(变量 / 数据)   是获取变量或者数据的整数部分
         从数据的 左侧起 解析获取 整数内容 
         console.log( parseInt(true) );                 // 都是 NaN            
         console.log( parseInt(false) );                                   
         console.log( parseInt(null) );                                    
         console.log( parseInt(undefined) );                               
         console.log( parseInt( {name:'zhangsan'} ) );                     
         console.log( parseInt( function fun(){console.log('abc')} ) ); 

         数组执行,是获取 数值部分 也就是 没有 []的部分
         1,2,3,4,5  整数部分是 1  1之后是逗号 逗号不是整数,之后的部分也就不算整数
         获取第一个数值的整数部分,如果有就获取,如果没有,结果是NaN
         console.log( parseInt( [1,2,3,4,5] ) );        // 结果是 1                      
         console.log( parseInt( [null,2,3,4,5] ) );     // 结果是 NaN 

         如果是整数就直接获取,如果是浮点数,或者科学计数法,就获取整数部分
         console.log( parseInt( 100 ) );          // 整数是直接获取
         console.log( parseInt( 0.0123 ) );       // 浮点数是获取整数部分
         console.log( parseInt( 3.123456e3 ) );   // 科学计数法是解析之后,获取整数部分

         字符串不同了
         如果是纯数字的字符串
         console.log( parseInt( '100' ) );         // 与数字的结果相同 
         console.log( parseInt( '0.0123' ) );      // 与数字的结果相同 

         console.log( parseInt( '3.123456e3' ) );   //3
         console.log( parseInt( '3abc' ) );   //3
         console.log( parseInt( '3.123' ) );   //3

 方法3 , parseFloat( 变量 / 数值 )
         获取浮点数部分
         console.log( parseFloat(true) );           // 都是 NaN            
         console.log( parseFloat(false) );                                   
         console.log( parseFloat(null) );                                    
         console.log( parseFloat(undefined) );                               
         console.log( parseFloat( {name:'zhangsan'} ) );                     
         console.log( parseFloat( function fun(){console.log('abc')} ) );         
        //数值, 整数,浮点数,都会完整获取
         console.log( parseFloat(100) );            //100
         console.log( parseFloat(100.1234) );       //100.1234
         console.log( parseFloat(1.234567e3) );     //1234.567

         // 关键是字符串
         // 从字符串的左侧起 解析 符合浮点数的部分
         console.log( parseFloat( '100' ) );         // 与数字的结果相同 
         console.log( parseFloat( '0.0123' ) );      // 与数字的结果相同 

         console.log( parseFloat( '3.123456e3' ) );  // 科学技术法会解析
         console.log( parseFloat( '3.1223abc' ) );        
         console.log( parseFloat( '3.123' ) );  
好了,这就是在JavaScript中数据类型的转化,希望可以帮助到你。
————————————————
版权声明:本文为CSDN博主「什什么都绘」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39406353/article/details/104864224

jQuery超详细总结

前端达人

jQuery超详细总结

文章目录

jQuery超详细总结

一 选择器

特殊选择器

二 筛选器

用在 jQuery 选择的元素后面

都是方法,对选择出来的元素进行二次筛选

三 文本操作

总结

四 元素类名操作

五 元素属性操作

在 H5 的标准下, 给了一个定义, 当你需要写自定义属性的时候,最好写成 data-xxx="值",当大家看到 data-xxx 的时候, 就知道这是一个自定义属性

六 元素样式操作

七 绑定事件

  1. on()方法是专门用来绑定事件
  2. one() 方法是专门用来绑定一个只能执行一次的方法
  3. off() 方法是专门用来解绑一个元素的事件的
  4. trigger() 方法是专门用来触发事件的方法
  5. hover()
  6. 常用事件

    八 节点操作
  7. 创建节点
  8. 插入节点
  9. 删除节点
  10. 替换节点
  11. 克隆节点

    九 获取元素尺寸

    尺寸: 元素的占地面积

    三套方法, 四种使用方式

    十 获取元素位置
  12. offset()
  13. position()

    十一 获取卷去的尺寸(页面滚动条)

    scrollTop()

    scrollLeft()

    十二 jQuery中的函数

    ready() 事件

    each() 方法

    十三 jQuery中的动画

    让元素出现不同的移动, 改变

    标准动画

    折叠动画

    渐隐渐显动画

    综合动画

    停止动画

    十四 jQuery发送ajax请求

    jQuery 里面帮我们封装好了几个方法

    专门用来发送 ajax 请求的

    jQuery 发送一个 GET 请求

    jQuery 发送一个 POST 请求

    jQuery 的 $.ajax 方法

    jQuery 的 ajax 全局钩子函数

    十五 jQuery 发送一个 jsonp 请求

    十六 jQuery 的多库并存机制

    十七 jQuery 的插件扩展机制

    十八 jQuery 的拷贝对象问题

    十九 jQuery 的插件

    jQuery 是一个前端库,也是一个方法库

    他里面封装着一些列的方法供我们使用

    我们常用的一些方法它里面都有,我们可以直接拿来使用就行了

    jQuery 之所以好用,很多人愿意使用,是因为他的几个优点太强大了

    优质的选择器和筛选器

    好用的隐式迭代

    强大的链式编程

    因为这些东西的出现,很多时候我们要做的事情被 “一行代码解决”

    接下来我们就来认识一下 jQuery

    一 选择器

    $()

    css怎么获取元素这里就怎么写

    获取的是一组元素,当里面是id时,这组元素只有一个内容

    特殊选择器

    :first $('li:first') 获取元素集合里的 第一个元素

    //  console.log($('li:first'))

    1

    :last $('li:last') 获取元素集合里的 最后一个元素

    :eq() $('li:eq()')获取元素集合里 索引为n 的那个元素,索引从0开始

    :odd $('li:odd') 获取所有索引为 奇数 的元素

    :even $('li:even') 获取所有索引为 偶数 的元素

    二 筛选器

    用在 jQuery 选择的元素后面

    都是方法,对选择出来的元素进行二次筛选

    first() 筛选 元素集合里面的 第一个元素

    //  console.log($('li').first())

    1

    last() 筛选 元素集合里面的 最后一个元素

    eq(n) 筛选元素集合里 索引为n 的那个元素

    next() 筛选出来 元素 的下一个 兄弟元素

    nextAll() 筛选出 元素后面的 所有 兄弟元素

    nextAll(选择器) 筛选出元素后面的 所有兄弟元素 中符合选择器的元素

    nextUntil(选择器) 筛选出 元素后面的所有兄弟元素 直到 选中的元素为止 不包含选中的元素

    //  console.log($('span').nextUntil('.a10'))

    1

    prev() 筛选出来 元素 的上一个 兄弟元素

    prevAll() 筛选出 元素上面的 所有 兄弟元素 (元素集合中的元素 从上一个兄弟元素开始排序)

    prevAll(选择器) 筛选出 元素上面的 所有兄弟元素 中符合选择器的元素

    prevUntil(选择器) 筛选出 元素上面的所有兄弟元素 直到 选中的元素为止 不包含选中的元素

    //  console.log($('span').prevUntil('.a10'))

    1

    parent() 筛选出元素的 父元素

    parents()筛选出元素的 所有祖先元素 直到html元素

    parents(选择器)拿到 所有祖先元素中的符合选择器的元素

    parentsUntil(选择器)筛选出元素的 所有的祖先元素 直到某一个元素 不包含该元素

    //  console.log($('span').parents('body'))

    // console.log($('span').parentsUntil('html'))



    children() 筛选出元素的 所有子级元素



    children(选择器) 筛选出元素 所有子级元素中的 符合选择器的元素

    siblings() 筛选出所有的兄弟元素 不包含 自己



    siblings(选择器) 筛选出所有的兄弟元素中的 符合选择器的元素

    find(选择器)



    筛选 一个元素后代中的 符合选择器的元素

    在一个元素集合的每一个元素中 查找后代元素 符合选择器的元素

    index() 获取元素的索引位置



    索引位置是指 是该父元素下的第几个元素 拿到的是 数字

    三 文本操作

    html() 一个读写的属性

    html()不传递 参数的时候 就是获取元素内部的超文本内容

    html(参数)传递 参数的时候 就是设置元素内部的超文本内容

    text() 一个读写的属性

    text()不传递 参数的时候 就是获取元素内部的超文本内容

    text(参数)传递 参数的时候 就是设置元素内部的超文本内容

    val() 一个读写的属性 操作 input 标签

    val()不传递参数的时候, 就是获取标签的 value 值

    val(参数)传递一个参数的时候, 就是设置标签的 value 值

    总结

    获取

    html() 只能获取第一个元素的超文本内容

    text() 能获取元素集合内所有元素的文本内容合

    val() 只能获取第一个元素的 value 值

    设置

    html() 给元素集合内所有元素设置超文本内容

    text() 给元素集合内所有元素设置文本内容

    val() 给元素集合内所有元素设置 value 值

    四 元素类名操作

    addClass() 添加类名

    执行这个方法会给元素集合里面所有的元素添加上固定的类名

    如果有就不添加, 不存在这个类名时添加

    removeClass() 移除类名

    执行这个方法删除 元素集合里面所有元素 的指定类名

    toggleClass()切换类名

    执行这个方法会给元素集合里面的所有元素切换类名

    本身存在这个类名, 删除类名

    本身不存在这个类名, 添加类名

    hasClass() 判断有没有某一个类名

    返回的时一个布尔值, 表示这个类名是否存在

    五 元素属性操作

    在 H5 的标准下, 给了一个定义, 当你需要写自定义属性的时候,最好写成 data-xxx=“值”,当大家看到 data-xxx 的时候, 就知道这是一个自定义属性

    attr() 和 removeAttr()



    attr: attribute 属性

    attr()

    是一个读写的方法

    attr(要读取的属性名): 传递一个参数的时候是读取

    attr(属性名, 属性值): 传递两个参数的时候是设置

    removeAttr() 专门用来移除属性的

    attr 这套方法的注意:

    所有的属性都会显示在标签上(原生属性和自定义属性)

    不管你设置的是什么数据类型, 都会给你变成字符串

    removeAttr 删除 attr 设置的属性, 有多少删除多少(针对自定义属性)

    prop() 和 removeProp()



    prop: property 属性

    prop()

    一个读写的方法

    prop(要读取的属性名): 传递一个参数的时候是读取

    prop(属性名, 属性值): 传递两个参数的时候是设置

    removeProp()专门用来移除属性的

    prop 这套方法的注意:

    非原生属性, 不会显示在标签上, 但是你可以获取使用

    你存储的是什么数据类型, 获取的时候就是什么数据类型

    removeProp 删除 prop 设置的属性, 有多少删除多少(针对自定义属性)

    removeProp() 不能删除原生属性 id class style 等等

    data() 和 removeData()



    data: data 数据

    data()

    一个读写的方法

    data(要读取的属性名): 传递一个参数的时候是读取

    data(属性名, 属性值): 传递两个参数的时候是设置

    removeData() 专门用来删除数据的

    data 这套方法的注意:

    和元素的原生属性没有关系, 可以设置 id, 但是和元素的 id 没关系

    就是在元素身上给你开辟一个地方, 存储一些数据

    你设置的是什么数据类型, 拿到的就是什么数据类型

    removeData 删除 data 设置的属性

    data() 方法也能读取写在标签上的 H5 标准自定义属性

    三个方法存储内容

    attr 设置的自定义属性存储在标签身上

    prop 设置的自定义属性存储在元素对象里面

    data 设置的自定义属性存储在元素对象里面单独开辟的一个对象

    六 元素样式操作

    css()

    一个读写的属性

    不同操作需要 传递 不同的参数

    css('样式名称')

    css('width')

    获取元素的样式值, 不管是行内样式还是非行内样式都能获取

    css('样式名称', '样式的值')

    css('width', '200px')

    设置元素的样式值, 元素集合能获取多少个元素就置多少个元素

    设置的时候, 所有的单位都可以不写, 默认添加 px为单位

    css(对象)

    css({ width: 100, 不写单位默认是 px height: '200px', opacity: 0.5 })

    批量设置 css 样式

    给元素集合里面的所有元素, 批量设置样式

    七 绑定事件
  14. on()方法是专门用来绑定事件

    jQuery 里面通用的事件绑定方式

    不同操作 传递 不同参数

    on方法的各种参数描述

    on('事件类型', 事件处理函数)

    给元素集合内所有的元素绑定一个事件

    // 给 $('li') 获取到的所有元素绑定一个点击事件

        // $('li').on('click', function () {

        //   console.log('我被点击了')

        // })



    on('事件类型', '事件委托', 事件处理函数)

    把 事件委托 位置的元素的事件 委托给了前面元素合

        // 给所有的 li 标签设置事件委托, 委托给了 ul

        // $('ul').on('click', 'li', function () {

        //   console.log('我被点击了, 事件委托')

        // })



    on('事件类型', 复杂数据类型, 事件处理函数)

    给每一个元素绑定一个事件, 复杂数据类型是发事件时候传递的参数

     //   每一个 li 点击的时候, 都能得到中间那个对象

        //   就是事件对象了面

        // $('li').on('click', { name: 'Jack', age: 18 }, function (e) {

        //   console.log('我被点击了, li')

        //   console.log(e)

        // })

    1

    2

    3

    4

    5

    6

    on('事件类型', '事件委托', 任意数据类型, 件处函数)

    做一个事件委托的形式, 第三个参数位置的数据

    是触发事件的时候, 可以传递进去的数据

    on(对象)

    给一个元素绑定多个事件的方式 不能传参数

     // $('ul').on({

        //   click: function () { console.log('点击事件') },

        //   mouseover: function () { console.log('移入事件') },

        //   mouseout: function () { console.log('移出事件') }

        // })


  15. one() 方法是专门用来绑定一个只能执行一次的方法

    传递的参数个数和意义 于 on 方法一摸一样

    绑定上的事件只能执行一次
  16. off() 方法是专门用来解绑一个元素的事件的

    使用方式

    off('事件类型') : 给该事件类型的所有事件处理函数解绑

    off('事件类型', 事件处理函数) : 解绑指定事件处理函数

    注意:on 和 one 绑定的事件它都能移除
  17. trigger() 方法是专门用来触发事件的方法

    不通过点击, 通过代码把事件触发了

    trigger('事件类型') : 把该元素的事件给触发了
  18. hover()

    jQuery 里面唯一一个很特殊的事件函数

    表示一个鼠标悬停动作

    只有一个使用方式

    hover(鼠标移入的时候触发, 鼠标移出的时候触发)

     // hover 事件

        //   如果你只传递一个函数, 那么移入移出都触发这一个函数

        $('ul')

          .hover(

            function () { console.log('鼠标移入') },

            function () { console.log('鼠标移出') }

          )


  19. 常用事件

    jQuery 把一些常用事件直接做成了函数



    click()

    mouseover()

    . . . . . .

    直接使用就可以了



    使用 click 举一个例子



    click(事件处理函数)

    click(参数, 事件处理函数)

    参数: 触发事件的时候传递到事件里面的数据

        // 常用事件

        // 给 ul 绑定了一个点击事件

        // $('ul').click([1, 2, 3, 4, true], function (e) {

        //   console.log('你好 世界')

        //   console.log(e)

        // })

    1

    2

    3

    4

    5

    6

    八 节点操作
  20. 创建节点

    对应原生 js 里面的 createElement()

    $('html 格式的文本')

    // 创建一个 div 元素

        console.log($('<div>我是一个创建出来的节点</div>'))

    1

    2
  21. 插入节点

    对应原生 js 里面的 appendChild()

    内部插入

    放在页面元素的子元素位置, 放在末尾

    页面元素.append(要插入的元素)

    要插入的元素.appendTo(页面元素)

    放在页面元素的子元素位置, 放在最前

    页面元素.prepend(要插入的元素)

    要插入的元素.prependTo(页面元素)

    外部插入

    放在页面元素的下一个兄弟元素位置

    页面元素.after(要插入的元素)

    要插入的元素.insertAfter(页面元素)

    放在页面元素的上一个兄弟元素位置

    页面元素.before(要插入的元素)

    要插入的元素.insertBefore(页面元素)
  22. 删除节点

    对应原生 js 里面的 removeChild()

    页面元素.empty() -> 把自己变成空标签,将所有子元素移除

    页面元素.remove() -> 把自己移除

    没有删除某一个子节点的方法,因为 jQuery 的选择器的强大,直接找到要删除的节点, remove()
  23. 替换节点

    对应原生 js 里面的 replaceChild()

    页面元素.replaceWith(替换元素)

    替换元素.replaceAll(页面元素)
  24. 克隆节点

    对应原生 js 里面的 cloneNode()

    元素.clone()

    两个参数的值为 true或false

    第一个参数: 自己的事件是否克隆

    第二个参数: 子节点的事件是否克隆

    如果第一个参数的值为false,那么第二个参数不起作用,没有意义。

    不管你是否传递参数, 都会把所有后代元素都克隆下来

    元素 + 文本内容 + 属性 + 行内样式

    参数只决定是否克隆元素身上的事件

    九 获取元素尺寸

    尺寸: 元素的占地面积

    width 和 height

    padding

    border

    margin

    三套方法, 四种使用方式

    这些方法都是不考虑盒模型的状态(不管是什么型, 都是固定区域)

    width() 和 height()

    获取元素的 内容 区域的尺寸

    innerWidth() 和 innerHeight()

    获取元素的 内容 + padding 区域的尺寸

    outerWidth() 和 outerHeight()

    获取元素的 内容 + padding + border 区域的尺寸

    outerWidth(true) 和 outerHeight(true)

    获取元素的 内容 + padding + border + margin 区域的尺寸

    十 获取元素位置
  25. offset()

    offset: 偏移量

    是一个读写的属性

    读取

    不传递参数就是读取

    读到的元素相对于页面的位置关系

    返回值是一个对象 { left: xxx, top: xxx }

    书写

    传递一个对象就是写入 { left: xxx, top: xxx }

    注意: 绝对写入

    不管你本身和页面的尺寸是什么样,写多少就是多少
  26. position()

    postition: 定位

    只读的方法

    读取:

    元素相对于定位父级的位置关系

    得到的也是一个对象 { left: xxx, top: xxx }

    如果你写的是 right 或者 bottom, 会自动计算成 left 和 top 值给你

    十一 获取卷去的尺寸(页面滚动条)

    scrollTop()

    原生 js 里面 document.documentElement.scrollTop

    读写的方法

    不传递参数的时候就是获取卷去的高度

    传递一个参数就是设置卷去的高度

    scrollLeft()

    原生 js 里面 document.documentElement.scrollLeft

    读写的方法

    不传递参数的时候就是获取卷去的宽度

    传递一个参数的时候就是设置卷去的宽度

    十二 jQuery中的函数

    ready() 事件

    类似于 window.onload 事件,但是有所不同

    window.onload 会在页面所有资源加载行

    ready() 会在页面 html 结构加载完毕后执行

    也叫做 jQuery 的入口函数

    有一个简写的形式 $(function () {})

    each() 方法

    类似于 forEach(), 遍历数组的

    jQuery 的元素集合, 是一个 jQuery 数组, 不是一个数组, 不能使用 forEach()

    forEach语法: forEach(function (item, index) {})

    each语法:each(function (index, item) {})

    比较少用到, 因为 jQuery 隐式迭代 自动遍历

    十三 jQuery中的动画

    让元素出现不同的移动, 改变

    transition -> 过渡动画

    animation -> 帧动画

    标准动画

    show() 显示元素

    语法: show(时间, 运动曲线, 运动结束的函数)

    hide() 隐藏元素

    语法: hide(时间, 运动曲线, 运动结束的函数)

    toggle() 改变元素显示或隐藏(如果显示就隐藏,如果隐藏就显示)

    语法: toggle(时间, 运动曲线, 运动结束的函数)

    三个方法的参数都可以选填,不需要每个都填写

    折叠动画

    slideDown() 下滑显示

    语法: slideDown(时间, 运动曲线, 运动结束的函数)

    slideUp() 上滑隐藏

    语法: slideUp(时间, 运动曲线, 运动结束的函数)

    slideToggle() 切换滑动和隐藏

    语法: slideToggle(时间, 运动曲线, 运动结束的函数)

    渐隐渐显动画

    实质是透明的opacity的变化

    fadeIn() 逐渐显示

    fadeIn(时间, 运动曲线, 运动结束的函数)

    fadeOut() 逐渐消失

    fadeOut(时间, 运动曲线, 运动结束的函数)

    fadeToggle() 切换显示和消失

    fadeToggle(时间, 运动曲线, 运动结束的函数)

    以上三个方法的参数,均有默认值

    fadeTo() 设置元素透明度变为你指定的数字

    fadeTo(时间, 你指定的透明度, 运动曲线, 运动结束的函数)

    综合动画

    animate()

    基本上大部分的 css 样式都可以动画

    transform 不行, 颜色不行

    语法: animate({}, 时间, 运动曲线, 运动结束的函数)

    { }里面就写你要运动的 css 属性,默认单位为px

    停止动画

    让当前的动画结束

    因为 jQuery 的动画你一直点击,就会一直触发。即使不再点击让事件发生,还是会把没执行完的动画执行完毕。

    你点击 10 次, 他就会触发 10 次, 直到 10 次全都完毕才结束

    stop()

    当这个函数触发的时候, 就会让运动立刻停下来

    你运动到哪一个位置了就停止在哪一个位置

    finish()

    当这个函数触发的时候, 就会让运动立刻停下来

    不管你运动到了哪一个位置, 瞬间到达运动完成位置

    十四 jQuery发送ajax请求

    jQuery 里面帮我们封装好了几个方法

    专门用来发送 ajax 请求的

    $.get() -> 专门用来发送 get 请求的

    $.post() -> 专门用来发送 post 请求的

    $.ajax() ->

    发送什么请求都可以(get, post, put, delete)

    并且还可以发送一个 jsonp 请求

    jQuery 发送一个 GET 请求

    语法: $.get(请求地址, 需要携带到后端的参数, 成功的回调函数, 期望后端返回的数据类型)

    请求地址: 你要请求的后端接口地址(必填)

    携带参数: 你需要给后端传递的参数

    可以是一个固定格式的字符串 ‘key=value&key=value’

    也可以是一个对象 { a: 100, b: 200 }

    成功回调: 当请求成功的时候会执行的函数

    期望数据类型: 就是你是不是需要 jQuery 帮你解析响应体

    • 默认是不解析
    • 当你传递一个 ‘json’ 的时候, 会自动帮你执行 JSON.parse()

          // 打开页面就发送 GET 请求了

          // $.get('./server/get.php', 'a=100&b=200', function (res) {

          //   // res 就是后端返回的数据, 也就是响应体

          //   // console.log(JSON.parse(res))

          //   console.log(res)

          // }, 'json')



          // $.get('./server/get.php', { a: 300, b: 400 }, res => {

          //   console.log(res)

          // }, 'json')

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      jQuery 发送一个 POST 请求

      语法: $.post(请求地址, 需要携带到后端的参数, 成功的回调函数, 期望后端返回的数据类型)

      四个参数和 $.get 是一摸一样的

          // 打开页面就发送 POST 请求了

          // $.post('./server/post.php', 'c=hello&d=world', function (res) {

          //   console.log(res)

          // }, 'json')



          // $.post('./server/post.php', { c: '你好', d: '世界' }, res => {

          //   console.log(res)

          // }, 'json')



      jQuery 的 $.ajax 方法

      用来发送综合 ajax 请求的(GET, POST, PUT, …)

      语法: $.ajax(对象)对象是对本次请求的所有配置
    • $.ajax({

          url: '', // => 请求地址(必填)

          type: '', // => 请求方式(GET, POST, ...) 默认是 GET

          data: '', // => 携带到后端的参数

          dataType: '', // => 期望后端返回的数据类型, 默认不解析

          async: true, // => 是否异步, 默认是 true

          success: function () {}, // => 成功的回调

          error: function () {}, // => 失败的回调

          timeout: 数字, // 单位是 ms, 超时时间(超过你写的时间没有响应, 那么就算失败)

          cache: true, // 是否缓存, 默认是 true

          context: 上下文, // 改变回调函数里面的 this 指向

                  ...

                })



      $.ajax 里面失败的回调



      不光是请求失败的时候会触发

      jQuery 认定失败就是失败

      当 dataType 写成 json 的时候, jQuery 会帮我们执行 JSON.parse()

      当后端返回一个不是 json 格式的字符串的时候

      执行 JSON.parse() 就会报错

      也会执行失败的回调, 请求虽然成功, 但是解析失败了, 也是失败

      JSON.parse(‘你好 世界’) -> 就会报错了

      $.ajax 里面是否缓存的问题



      这个请求要不要缓存

      当两次请求地址一样的时候, 就会缓存

      如果你写成 false, 表示不要缓存

      jQuery 就会自动再你的请求后面加一个参数 =时间戳

      第一次请求 ./server/get.php?
      =11:10:01.325的时间戳

      第二次请求 ./server/get.php?_=11:10:02.326的时间戳

      $.ajax 里面的回调 this 指向问题



      ajax 的回调里面默认 this 指向被 jQuery 加工过的 ajax 对象

      context 的值你写的是谁, 回调函数里面的 this 就时谁

      $.ajax 里面的请求方式的问题



      $.ajax 这个方法里面, type 表示请求方式

      jQuery 还给了我们一个参数叫做 method,也表示请求方式

      当你写请求方式的时候

      可以写成 type: ‘POST’

      也可以写成 method: ‘POST’

      $.ajax 里面的接收响应的问题(2015年以后的版本才有 promise 的形式)



      jQuery 默认把 ajax 封装成了 promsie 的形式

      你可以用 success 选项接收成功的回调

      也可以用 .then() 的方式接收响应

      jQuery 的 ajax 全局钩子函数

      钩子: 挂在你的身上, 你的所有动作都和它有关系

      这些全局函数都是挂在 ajax 身上的, 这个 ajax 的每一个动作都和全局函数有关系

      全局的钩子函数

      1.ajaxStart()

      会在同一个作用域下多个 ajax 的时候, 第一个 ajax 之前开始的时候触发

      如果有多个 ajax 他只触发一次

      2.ajaxSend()

      每一个 ajax 再发送出去之前, 都会触发一下

      xhr.send() 之前触发

      ajaxSuccess()

      每一个 ajax 再成功的时候触发

      只要有一个 ajax 成功了就会触发

      ajaxError()

      每一个 ajax 再失败的时候触发

      只要有一个 ajax 失败了就会触发

      ajaxComplete()

      每一个 ajax 完成的时候触发

      只要有一个 ajax 完成了, 不管成功还是失败, 都会触发

      ajaxStop()

      会在同一个作用域内多个 ajax 的时候, 最后一个 ajax 完成以后触发

      如果有多个 ajax 它只触发一次

      作用: 通常用来做 loading 效果

       <img src="./loading.gif" alt="">

      // 利用ajax钩子函数 做一个lading效果  等待页面

       // 提前利用钩子函数准备 loading 效果

          // 每一次发送出去的时候都要显示图片

          $(window).ajaxSend(() => {

            $('img').show()

          })



          // 每一次完成的时候都要图片再隐藏起来

          $(window).ajaxComplete(() => {

            $('img').hide()

          })



          // 每次点击按钮的时候都会发送一个 ajax 请求

          $('button').click(() => {

            // 发送一个 ajax 请求

            $.ajax({

              url: './server/get.php',

              data: { a: 100, b: 200 },

              dataType: 'json',

              success: function (res) {

                console.log('请求成功了')

                console.log(res)

              }

            })

          })

      十五 jQuery 发送一个 jsonp 请求

      jQuery 也提供给我们发送 jsonp 请求的方式

      jsonp: 利用 script 标签的 src 属性来请求

      返回值: 是一个字符串, 字符串里面写了一个 函数名(后端传递给前端的参数)

      使用 $.ajax() 这个方法

      必须写的:dataType: 'jsonp'

      发送 jsonp 请求

      jQuery 帮我们准备好了一个函数名, 并且以参数的形式带到了后端

      jQuery 帮我们带过去的 callback 参数, 就是它准备好的函数名

      后端就应该返回一个 jQuery 准备好的函数名()

      其他参数

      jsonp: '', 你带到后端表示你函数名的那个 key, 默认值是 callback

      cache: false, 当 dataType === ‘jsonp’ 的时候, 默认 cache 就是 false

       // 发送一个 jsonp 请求

          $.ajax({

            url: 'http://127.0.0.1/server/jsonp.php',

            dataType: 'jsonp', // 表示我要发送一个 jsonp 请求

            jsonp: 'cb', // 表示参数里面的 cb 属性时我准备好的函数名

            cache: true, // 表示缓存本次请求

            success: function (res) {

              console.log(res)

            }

          })







          //   jQuery 准备好的函数名

          //     + jQuery34108160883644340862_1582255906750

          //     + 变量名包含 数字 字母 下划线 $

          //     + function jQuery34108160883644340862_1582255906750() {}



      十六 jQuery 的多库并存机制

      因为 jQuery 引入页面以后, 向全局添加了两个名字

      一个叫做 $

      一个叫做 jQuery

      万一有别的类库也起名叫做 jQuery 或者$ 怎么办

      当我两个库都需要使用的时候

      因为向全局暴露的名字一样, 就会发生冲突了

      谁的文件引再后面, 谁的名字就占主要位置了

      两个只能选择一个使用

      jQuery 提供了一个方法

      我可以不占用$ 或者 jQuery 这个名字

      noConflict()

      语法: $.noConflict() 或者jQuery.noConflict()

      当你执行了 noConflict() 以后, jQuery 就交出了$的控制权。

      jQuery向全局暴露的不在有$ 这个名字了。当你执行了noConflict(true) 以后, jQuery就交出了 $ 和jQuery 的控制权。

      交出去以后, 我的 jQuery 就用不了

      noConflict() 的返回值: 就是一个新的控制权

      你只要接收一个返回值, 你定好的变量是什么,jQuery 的控制权就是什么

       // 交出 $ 的控制权

          // $.noConflict()



          // 交出 $ 和 jQuery 的控制权

          // $.noConflict(true)



          // 改变 jQuery 的控制权

          var $$ = $.noConflict(true)



      十七 jQuery 的插件扩展机制

      jQuery 还提供给我们了一个机制, 就是你可以向 jQuery 里面扩展一些方法



      两个方法



      $.extend()

      扩展给 jQuery本身使用的

      语法:

      $.extend({ 你要扩展的方法名: function () {}, 你要扩展的方法名: function () {}, ... })

      使用的时候就是 $.你扩展的方法名()

      $.fn.extend() => $.extend($.fn, { 你扩展的方面名 })

      扩展给 jQuery 元素集合使用的



      语法 $.fn.extend({ 你要扩展的方法名: function () {}, 你要扩展的方法名: function () {}, ... })



      使用的时候就是 $(选择器).你扩展的方法名()



      $('div').html()



            // 1. 扩展给 jQuery 本身

          //    jQuery 本身没有操作 cookie 的方法

          // $.extend({

          //   setCookie: function (key, value, expires) {

          //     // 写上设置 cookie 的方法

          //     if (expires) {

          //       var time = new Date()

          //       time.setTime(time.getTime() - 1000 60 60 8 + 1000 expires)

          //       document.cookie = ${key}=${value};expires=${time}

          //     } else {

          //       document.cookie = ${key}=${value}

          //     }

          //   },

          //   getCookie: function (key) {

          //     // ...

          //   }

          // })



          // 使用我们扩展的方法去设置 cookie

          // $.setCookie('a', 100)

          // $.setCookie('b', 200, 10)





            // 2. 扩展给元素集合

          //    扩展一个全选的方法

          //    方法以执行, 就能让 input checkbox 变成选中状态或者不选中状态

          $.fn.extend({

            selectAll: function (type = true) {

              // type 就是你传递进来的选中或者不选中一个标志

              //   你不传递的时候, 我默认是 true, 你传递了就用你传递的

              // console.log(this) // 就是你调用的时候前面的哪个元素集合

              this.each(function (index, item) {

                // 让元素集合中的每一个 input 的 checked 属性为 true

                item.checked = type

              })



              // return 这个元素集合, 达到一个链式编程的效果

              return this

            }

          })





          $('button').click(() => {

            // 让所有 input 框变成选中状态

            console.log($('input').selectAll().attr('hello', 'world'))

          })



      十八 jQuery 的拷贝对象问题

      $.extend() 深拷贝 与 浅拷贝

      传递一个对象的时候, 可以做到插件扩展机制

      传递多个对象的时候, 可以将后面几个对象的内容复制到第一个对象里面

      语法:

      $.extend(是否深拷贝, 对象1, 对象2, 对象3, ...)

      是否深拷贝: 默认是 false, 可以不写

      从 对象2 开始, 后面所有对象的内容都会被拷贝到 对象1 里面

      再拷贝的时候, 如果有重复的 key, 那么以写在后面的为准(后来者居上)

      十九 jQuery 的插件

      基于 jQuery 使用的, 别人封装好的插件



      我们拿来使用就可以了, 前提就是要有 jQuery



      例子 一个叫做 jquery-validate 的插件



      专门用来做表单验证的

      你输入的内容是不是符合规则

      下载

      引入文件

      去复制粘贴


      <!-- 引入文件 -->
      <!-- 注意: 先引入 jQuery, 后引入 jquery-validate -->
      <script src="./jquery/jquery.min.js"></script>
      <!-- jquery-validate 这个文件依赖的 jquery -->
      <script src="./jquery-validate/jquery.validate.min.js"></script>
      <!-- 引入中文信息提示包, 必须在 jquery-validate 的后面 -->
      <script src="./jquery-validate/localization/messages_zh.min.js"></script>
      <script>
      
        // 选择到你要验证的表单的 form 标签
      //   执行 validate 方法
      //   {} 里面就写我们的验证规则
      $('#login').validate({
      // 你需要的验证规则
      rules: {
      // key 就是你要验证的哪个 input 框的 name 属性
      username: 'required', // 用户名必填
      password: { // 一个字段可以写多个验证方式
        required: true,
        minlength: 6, // 最少是六个
        maxlength: 12, // 最多十二个
      }
      },
      // 你自定义提示的文本内容
      messages: {
      // key 就是你验证的哪个 input 框的 name 属性
      username: '请输入用户名! ^_^',
      password: {
        required: '请输入密码!',
        minlength: '最少要输入 6 个字符噢!'
      }
      },
      // 表单的提交事件
      //    这个函数会在表单验证通过以后执行
      submitHandler: function (form) {
      // form 接收的就是你的 form 标签
      // console.log(form)
      // console.log('表单验证通过了, 我需要使用 ajax 去提交数据了')
      
      // 有一个 jQuery 的方法
      // serialize() 快速获取表单输入的数据
      //  $(form).serialize() 就能拿到这个 form 标签里面的表单数据
      // console.log($(form).serialize())  // username=admin&password=123456
      
      // 发送请求到后端
      $.post('./server/login.php', $(form).serialize(), res => {
        console.log(res)
      }, 'json')
      }
      })
      

      ————————————————
      版权声明:本文为CSDN博主「孔四月」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://blog.csdn.net/k464746/article/details/104685150

Js闭包

前端达人

所谓闭包就是说,闭包是指有权访问另外一个函数作用域中的变量的函数.可以理解为(能够读取其他函数内部变量的函数)

闭包的三大特点为(既是优点,也是缺点):

1,函数作用域空间不会被销毁

优点是:空间中的内容,永远存在

缺点是:占用大量的内存空间

2,可以从外部访问函数内部的变量

优点是:使用变量数据方便

缺点是:容易泄露数据信息

3,保护私有作用域变量

优点是:确保私有作用域变量一直存在

缺点是:占用内存空间 闭包的最大问题是:有可能造成占用大量的内存空间,降低程序的执行效率,甚至有可能造成数据溢出或者是数据泄露 因为为了保护数据的安全性,特殊情况下,才会使用闭包举例来说:

// 记数器:



//全局变量  全局变量降低函数的独立性

1

// var count = 0;

// function add(){

// return count++;

// }

// console.log(add());

// console.log(add());

// console.log(add());



//局部变量  函数执行外  局部变量销毁

1

// function add(){

// var count = 0;

// return count++;

// }

// console.log(add());

// console.log(add());

// console.log(add());



//plus定义在add的内部,可以访问add局部变量count

//f为一个全局变量,通过赋值后,成为add的返回值,也就是plus方法

//访问到了add中的局部变量count

//所以count虽然是局部变量,但不允许被销毁,plus就是闭包

1

2

3

4

// function add(){

// var count = 0;

// function plus(){

// return count++;

// }

// return plus;

// }

//

// var f = add();

//

// console.log(f());

// console.log(f());

// console.log(f());



//变身

1

// function add(){

// var count = 0;

// return function(){

// return count++;

// }

// }

//

// var f = add();

//

// console.log(f());

// console.log(f());

// console.log(f());



//继续变身

1

// var f = (function (){

// var count = 0;

// return function(){

// return count++;

// }

// }());

//

// console.log(f());

// console.log(f());

// console.log(f());

//JS中,没有块作用域,但是在闭包的写法里,可以体现出来。

function outerFunc(){

var outVar = 10;

var innerF = function (){

var innerVar = 20;//该变量虽然隶属于outerFunc内部,但是它的作用域范围只在innerF对应的函数体内,属于块级作用域

}

alert(innerVar);

return innerF;

}



闭包的作用:

正常函数执行完毕后,里面声明的变量被垃圾回收处理掉,但是闭包可以让作用域里的 变量,在函数执行完之后依旧保持没有被垃圾回收处理掉



可以读取函数内部的变量

让这些变量的值始终保持在内存中。

增加块级作用域

总结:

1、 闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。

2、 闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

3、不必纠结到底怎样才算闭包,其实你写的每一个函数都算作闭包,即使是全局函数,你访问函数外部的全局变量时,就是闭包的体现。







————————————————

版权声明:本文为CSDN博主「澈野」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/fie_ld/article/details/104595753

html+css基础入门学习教程之HTML 样式

前端达人

HTML 样式



通过使用 HTML4.0,所有格式化代码均可移出 HTML 文档,然后移入一个独立的样式表。



先来看一个例子,代码如下:



<head>

    <style type="text/css">

        h1 {color: red}

        p {color: blue}

    </style>

</head>



<body>

    <h1>header 1</h1>

    <p>A paragraph.</p>

</body>

页面上显示为:



header 1



A paragraph.



当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化。有以下三种方式来插入样式表:



外部样式表 link



当样式需要被应用到很多页面的时候,外部样式表将是理想的选择。使用外部样式表,你就可以通过更改一个文件来改变整个站点的外观。



<head>

<link rel="stylesheet" type="text/css" href="css/style.css">

</head>

link : 定义资源引用

rel : 告诉浏览器引用的是一个样式表文件

type : 文件类型

href : 文件地址



内部样式表



当单个文件需要特别样式时,就可以使用内部样式表。你可以在 head 部分通过 <style> 标签定义内部样式表。



<head>

<style type="text/css">

    body {background-color: red}

    p {margin-left: 20px}

</style>

</head>

style : 定义样式定义



新建一个前端学习qun438905713,在群里大多数都是零基础学习者,大家相互帮助,相互解答,并且还准备很多学习资料,欢迎零基础的小伙伴来一起交流。



内联样式



当特殊的样式需要应用到个别元素时,就可以使用内联样式。 使用内联样式的方法是在相关的标签中使用样式属性。样式属性可以包含任何 CSS 属性。以下实例显示出如何改变段落的颜色和左外边距。



<p style="color: red; margin-left: 20px">

This is a paragraph

</p>

优先级说明



(外部样式)External style sheet < (内部样式)Internal style sheet < (内联样式)In



1.下列方法表示调用外部样式表的是?



A<style type="text/css">h1 {color: red }</style>



B<link rel="stylesheet" type="text/css" href="css/style.css">



C<p style="color: red; margin-left: 20px">style</p>



2.下面三种方法可以起到改变文档样式的是?



A<style type="text/css">h1 {color: red }</style>



B<link rel="stylesheet" type="text/css" href="css/style.css">



C<p style="color: red; margin-left: 20px"></p>



D以上三种都可以

————————————————

版权声明:本文为CSDN博主「html前端基础入门教程」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/htkms87/article/details/104600003

利用键盘控制小方块的移动

前端达人

原理

  1. 利用键盘控制移动,则需要了解onkeydown函数,表示某个按键被按下,可以以此绑定一个事件响应函数,当键盘被按下时候,触发此事件,进行移动
  2. keyCode 对于keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。 因此我们可以根据keycode返回的字符码来判断用户所按下的键,下面就是一个用于测试上下左右按键的js代码,经过我的测试之后,返回37 38 39 40;

    window.onload = function(){
                var box = document.getElementById("box");
                document.onkeydown = function(event){
                    event = event || window.event;
                    console.log(event.keyCode);
                }           
            };
    3



    3.方块的移动实际上就是坐标的改变,因此需要offsetLeft 和offsetTop 来获得当前方块的坐标,然后将坐标进行一定的更改,就可以实现移动的效果了,下面给出代码

    window.onload = function() {
                document.onkeydown = function(event) {
                    event = event || window.event;
                    //设置移动速度
                    var speed = 10;
                    //当ctrl和方向按键同时按下时,提升移动速度
                    if(event.ctrlKey) {
                        speed = 50;
                    }
                    //获取div
                    var box01 = document.getElementById("box01");
                    switch(event.keyCode) {
                        /*keyCode返回按下按键的编码
                         * 37 向左
                         * 38向上
                         * 39向右
                         * 40向下
                         */
                        case 37:
                            box01.style.left = box01.offsetLeft - speed + "px";
                            break;
                        case 39:
                            box01.style.left = box01.offsetLeft + speed + "px";
                            break;
                        case 38:
                            box01.style.top = box01.offsetTop - speed + "px";
                            break;
                        case 40:
                            box01.style.top = box01.offsetTop + speed + "px";
                            break;
    
                    }
                };
    
            };
    



    这样就可以简单实现方块的移动,但是此时我们会发现一个问题,当我们进行移动的时候,按住按键不松手,理论上方块应该直接平滑的进行移动,但实际上并非如此,第一下它会有一个小的停顿,这实际上是浏览器防止误触所设置的,因此我们需要对此进行优化
    解决方案

    这里我采用了定时器的做法来解决这个问题,因为控制移动的因素有两个,一个是控制方向,一个是控制速度,控制方向没有问题,因此我们需要改变速度
    setInterval(function(){},time);这是一个定时器,我们只需要在time时间内调用一次函数,就可以解决停顿的问题了
    下面附上修改后的完整代码


    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #box01 {
                width: 100px;
                height: 100px;
                background-color: #008000;
                position: absolute;
            }
        </style>
        <script type="text/javascript">
            window.onload = function() {
    
                //获取div
                var box01 = document.getElementById("box01");
                //设置移动速度
                var speed = 10;
                //设置移动的方向
                var dir = 0;
    
                setInterval(function() {
                    switch(dir) {
                        /*keyCode返回按下按键的编码
                         * 37 向左
                         * 38向上
                         * 39向右
                         * 40向下
                         */
                        case 37:
                            box01.style.left = box01.offsetLeft - speed + "px";
                            break;
                        case 39:
                            box01.style.left = box01.offsetLeft + speed + "px";
                            break;
                        case 38:
                            box01.style.top = box01.offsetTop - speed + "px";
                            break;
                        case 40:
                            box01.style.top = box01.offsetTop + speed + "px";
                            break;
    
                    }
    
                }, 50)
    
                document.onkeydown = function(event) {
                    event = event || window.event;
    
                    //当ctrl和方向按键同时按下时,提升移动速度
                    if(event.ctrlKey) {
                        speed = 50;
                    } else {
                        speed = 10;
                    }
                    //使dir等于keycode的值
                    dir = event.keyCode;
    
                    //当鼠标松开时,停止移动         ---如果不写这一个会造成无法停止移动的效果
                    document.onkeyup = function() {
                        dir = 0;
                    };
    
                };
    
            };
        </script>
    </head>
    
    <body>
        <div id="box01"></div>
    </body>
    

</html>

————————————————

版权声明:本文为CSDN博主「loving-cat」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_42878211/article/details/104558443



Vuex的一些用法

前端达人

vuex的基础

1,状态管理(共享)

缓存数据==>内存, 只要刷新页面,数据就丢了

订单,详情等,,,不适用vuex缓存数据



用于



非父子通信的问题

缓存后端数据,提高用户体验

注意:

vuex只能有一个store,

为了防止多人修改,我们切割成子store, 再合并成唯一一个大的store对象

模块写法

import Vue from 'vue'
import Vuex from 'vuex'
import cinema from './module/cinemaModule'
import tabbar from './module/tabbarshowModule'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {

  }, // "全局"状态
  mutations:{

  },//唯一修改状态的地方
  //异步处理
  actions:{
  },
  // 对上面的“全局状态”进行数据处理, 类似于vue中的计算属性
  getters:{
  },

  modules:{
    cinema,
    tabbar
  }
})
export default store

2,子模块的写法

const module = {
  namespaced:true, //命名空间
  state :{
    cinemaList:[]
  },
  actions:{
    store.commit("setCinemaList",res.data.data.cinemas) //支持传参
  },
  mutations:{
    setCinemaList(state,data){
      console.log("setCinemaList",data)
      state.cinemaList = data
    }
  },
  getters:{
    topDataList(state){
      //state形参s, vuex自动调用时候,传来值
      return state.cinemaList.slice(0,5)
    }
  }
}

export default module

3,为了防止页面刷新丢失数据,所以还得找到其他插件来帮忙

import createPersistedState from "vuex-persistedstate"; //在index.js页面加入这个插件

// 加入下面的代码
const store = new Vuex.Store({
  plugins: [createPersistedState({
    reducer(val){
      return {
        user: val.user
      }
    }
  })]


————————————————
版权声明:本文为CSDN博主「m0_46436313」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_46436313/article/details/104572076

javascript设计模式九:中介者模式

前端达人

中介者对象践行了最少知识原则,指一个对象尽可能少的了解别的对象,从而尽量减少对象间耦合程度。这样各个对象只需关注自身实现逻辑,对象间的交互关系交由中介者对象来实现和维护。



需求背景:



手机购买页面,在购买流程中,可以选择手机的颜色及输入购买数量,同时页面有两个展示区域,分别向用户展示刚选择好的颜色和数量。还有一个按钮动态显示下一步的操作,我们需要查询该颜色手机对应的库存,如果库存数量少于这次购买的数量,按钮将被禁用并显示库存不足,反之按钮可以点击并显示放入购物车。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>中介者模式 购买商品</title>
</head>
<body>
    选择颜色: 
    <select id="colorSelect">
        <option value="">请选择</option>
        <option value="red">红色</option>
        <option value="blue">蓝色</option>
    </select>

    输入购买数量:
    <input type="text" id="numberInput">

    您选择了颜色:<div id="colorInfo"></div><br>
    您输入了数量:<div id="numberInfo"></div><br>

    <button id="nextBtn" disabled>请选择手机颜色和购买数量</button>

</body>
<script>

// 最初级的写法
var colorSelect = document.getElementById('colorSelect'),
    numberInput = document.getElementById('numberInput'),
    colorInfo = document.getElementById('colorInfo'),
    numberInfo = document.getElementById('numberInfo'),
    nextBtn = document.getElementById('nextBtn');

var goods = {
    'red': 3,
    'blue': 6
}

colorSelect.onchange = function(){
    var color = this.value,
        number = numberInput.value,
        stock = goods[color]

    colorInfo.innerHTML = color;

    if(!color){
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请选择手机颜色';
        return;
    }

    if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请输入正确的购买数量';
        return;
    }

    if(number > stock){     //当前选择数量大于库存量
        nextBtn.disabled = true;
        nextBtn.innerHTML = '库存不足';
        return;
    }

    nextBtn.disabled = false;
    nextBtn.innerHTML = '放入购物车';
}

numberInput.oninput = function(){
    var color = colorSelect.value,
        number = this.value,
        stock = goods[color]

    colorInfo.innerHTML = color;

    if(!color){
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请选择手机颜色';
        return;
    }

    if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
        nextBtn.disabled = true;
        nextBtn.innerHTML = '请输入正确的购买数量';
        return;
    }

    if(number > stock){     //当前选择数量大于库存量
        nextBtn.disabled = true;
        nextBtn.innerHTML = '库存不足';
        return;
    }

    nextBtn.disabled = false;
    nextBtn.innerHTML = '放入购物车';
}

</script>
</html>

在上个示例中,对象间联系高度耦合,只是两个输入框还好,但如果有多个的话,相互联系就非常复杂了,此时就要考虑用到中介者模式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>中介者模式 购买商品</title>
</head>
<body>
    选择颜色: 
    <select id="colorSelect">
        <option value="">请选择</option>
        <option value="red">红色</option>
        <option value="blue">蓝色</option>
    </select>

    选择内存: 
    <select id="memorySelect">
        <option value="">请选择</option>
        <option value="32G">32G</option>
        <option value="16G">16G</option>
    </select>

    输入购买数量:
    <input type="text" id="numberInput">

    您选择了颜色:<div id="colorInfo"></div><br>
    您选择了内存:<div id="memoryInfo"></div><br>
    您输入了数量:<div id="numberInfo"></div><br>

    <button id="nextBtn" disabled>请选择手机颜色、内存和购买数量</button>
</body>
<script>
    var goods = {
        'red|32G': 3,
        'red|16G': 0,
        'blue|32G': 1,
        'blue|16G': 6
    }

    //引入中介者
    var mediator = (function(){
        var colorSelect = document.getElementById('colorSelect'),
            memorySelect = document.getElementById('memorySelect'),
            numberInput = document.getElementById('numberInput'),
            colorInfo = document.getElementById('colorInfo'),
            memoryInfo = document.getElementById('memoryInfo'),
            numberInfo = document.getElementById('numberInfo'),
            nextBtn = document.getElementById('nextBtn');

        return {
            changed: function(obj){
                var color = colorSelect.value,
                    memory = memorySelect.value,
                    number = numberInput.value,
                    stock = goods[color + '|' + memory];

                if(obj == colorSelect){      //如果改变的是选择颜色下拉框
                    colorInfo.innerHTML = color;
                }else if(obj == memorySelect){
                    memoryInfo.innerHTML = memory;
                }else if(obj == numberInput){
                    numberInfo.innerHTML = number;
                }

                if(!color){
                    nextBtn.disabled = true;
                    nextBtn.innerHTML = '请选择手机颜色';
                    return;
                }

                if(!memory){
                    nextBtn.disabled = true;
                    nextBtn.innerHTML = '请选择手机内存';
                    return;
                }

                if(!number){
                    nextBtn.disabled = true;
                    nextBtn.innerHTML = '请填写手机数量';
                    return;
                }

                if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
                    nextBtn.disabled = true;
                    nextBtn.innerHTML = '请输入正确的购买数量';
                    return;
                }

                if(number > stock){     //当前选择数量大于库存量
                    nextBtn.disabled = true;
                    nextBtn.innerHTML = '库存不足';
                    return;
                }

                nextBtn.disabled = false;
                nextBtn.innerHTML = '放入购物车';
            }
        }
    })()

    colorSelect.onchange = function(){
        mediator.changed(this)
    }

    memorySelect.onchange = function(){
        mediator.changed(this)
    }

    numberInput.oninput = function(){
        mediator.changed(this)
    }

    //以后如果想要再增加选项,如手机CPU之类的,只需在中介者对象里加上相应配置即可。
</script>
</html>
在实际开发中,还是要注意选择利弊,中介者对象因为包含对象间交互的复杂性,所以维护成本可能也会较高。在实际开发中,最优目的还是要快速完成项目交付,而非过度设计和堆砌模式。有时对象间的耦合也是有必要的,只有当对象间复杂耦合确实已经导致调用与维护难以为继,才考虑用中介者模式。

————————————————
版权声明:本文为CSDN博主「一期一会」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34832846/article/details/85989945

日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档