WEB - jQuery

about

https://jquery.com/

https://www.bootcdn.cn/jquery/

what?

摘自:https://www.bootcdn.cn/jquery/

​ jQuery 是一个高效、精简并且功能丰富的 JavaScript 工具库。它提供的 API 易于使用且兼容众多浏览器,这让诸如 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作更加简单。

why?

HTML元素选取(选择器)、HTML元素操作、CSS操作、HTML事件处理、JS动画效果、链式调用、读写合一、浏览器兼容、易扩展插件、Ajax封装.......

how?

  1. 使用前先引入。
  2. 使用jQuery:
    • jQuery核心函数
    • jQuery核心对象
  3. 区别两种jQuery文件:
    • 开发版(测试版)
    • 生产版(压缩版)
  4. 区别两种引用jQuery库的方式:
    • 服务器本地库,开发测试时使用,加重了服务器负担,上线时一般不使用这种方式
    • CDN远程库,项目上线时,一般使用比较靠谱的CDN资源库,减轻服务器压力
  5. 区别不同的jQuery版本:
    • 1.x,兼容老版本IE,但文件更大,目前用的较多
    • 2.x,部分IE8及以下不支持,文件小,执行效率更高
    • 3.x,提供了一些新的API,提供不包含Ajax/动画API的版本

future

截止到2021年,三大前端框架流行之后,尤其是在国内vue流行之后,jQuery慢慢的没落了.......

jQuery核心概念

引入jQuery

想要使用jQuery必须先引入,本地引入的话,要先下载,下载可以直接去官网下载,也可以去cdn上面下载。

而引入的两种方式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 1. 本地引入 -->
<script src="jquery-1.11.3.min.js"></script>
<!-- 2. 引入cdn -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    // 必须先引入再使用
    // 使用都是通过$来
    alert($)
</script>
</body>
</html>

jQuery核心函数

以jQuery1.11.3版本源码为例。

在jQuery的源码文件中的最后几行,一个连等之后,将jQuery返回:

重点在于这个jQuery是啥?在源文件的前几行:

jQuery的核心函数就是$或者jQuery,这俩货等价。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="jquery-1.11.3.min.js"></script>
<script>
    console.log(typeof $); // function
    console.log($ === jQuery); // true
    console.log(window.$ === jQuery); // true
</script>
</body>
</html>

jQuery定义了这个全局的函数供我们调用,它即可以作为一般函数调用,且根据传递参数的类型或者格式不同,就能实现不同的功能,如下面的示例。

jQuery的四种传参方式

通过不同的传参方式,实现不同的功能,jQuery中共有4种传参方式。

  1. 当参数为函数时,则约等于页面加载完成(window.onload)完成的回调函数。
  2. 当参数为选择器字符串时,通过选择器去匹配元素,并封装成jQuery对象返回。
  3. 当参数为DOM对象时,它会将DOM对象转换为jQuery对象。
  4. 当参数为html标签字符串时,它会将当前标签创建并转为jQuery对象。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 需求:点击按钮,添加input框 -->
<button class="btn">点我添加input框</button>
<div class="box1"></div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    // 首先如果参数是函数的话,则约等于页面加载完成(window.onload)完成的回调函数
    // $(); // 相当于函数加括号执行,只不过这个函数是jQuery的核心函数而已
    $(function () {});
    window.onload = function () {};
    
    // 1. 当参数为函数时,则约等于页面加载完成(window.onload)完成的回调函数
    $(function () {
        // 2. 当参数为选择器字符串时,通过选择器去匹配元素,并封装成jQuery对象返回。
        $(".btn").click(function () {
            // 3. 当参数为DOM对象时,它会将DOM对象转换为jQuery对象。
            console.log(this.innerHTML);  // this是dom对象,它没有html方法,所以要将它转为jQuery对象
            console.log($(this).html()); // jQuery对象有html方法
            // 当参数为html标签字符串时,它会将当前标签创建并转为jQuery对象。
            $('<input type="text"><br />').appendTo(".box1");
        });
    })
</script>
</body>
</html>

也能作为对象调用其封装好的方法,此时$就是个工具对象,这个也非常好理解,就是使用jQuery提供的方法。

如下示例中,我们通过原生js和jQuery来分别获取div中的值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="box1">Hello jQuery!</div>
<button id="btn1">原生js获取</button>
<button id="btn2">jQuery获取</button>
    
<script src="jquery-1.11.3.min.js"></script>
<script>
    // 原生js实现
    window.onload = function () {
        let btn1 = document.getElementById('btn1');
        let box1 = document.getElementsByClassName('box1')[0];
         btn1.onclick = function () {
             console.log(box1.innerHTML);
         };
    };
    // jQuery实现
    $(function () {
        // 通常,我们通过jQuery获取的元素对象,我们称其为jQuery对象,在变量命名时都会在最前面加个$以示区分
        let $btn2 = $("#btn2");
        $btn2.click(function () {
        console.log($(".box1").html());
    });
    });
</script>
</body>
</html>

由上例的对比可以看到,无论是元素选择还是取值,jQuery都非常简洁。

jQuery核心对象

所谓的jQuery核心对象,也就是执行jQuery核心函数返回的对象。

jQuery对象内部包含的是dom元素对象的伪数组(一个或多个dom元素对象)。

jQuery对象提供了很多属性和方法,可以让我们更方便的操作dom元素。

  • 基本行为:获取伪数组长度、索引、循环伪数组、返回其索引位置。
  • 属性:操作内部标签属性和值。
  • CSS:操作标签的样式。
  • 文档:对标签进行增删改操作。
  • 筛选:根据指定规则过滤内部的标签。
  • 事件:处理监听相关。
  • 效果:实现一些动画效果。

举个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <!--<p>p1</p>-->
    <button id="btn1">btn1</button>
    <button id="btn2">btn2</button>
    <button id="btn3">btn3</button>
    <button id="btn4">btn4</button>
</div>
    
<script src="jquery-1.11.3.min.js"></script>
<script>
    let $btns = $("button");
    /* 示例1:统计一共有多少个按钮 */
    // console.log($btns.size()); // 4
    // console.log($btns.length); // 4

    /* 示例2:取出第二个按钮的文本 */
    // 伪数组中存储的是dom元素,所以可以通过$btns[1]取出来
    // console.log($btns[1].innerHTML); // btn2
    // 也可以通过jQuery的eq方法根据索引取值
    // console.log($btns.eq(1).html()); // btn2

    /* 示例3:输出所有按钮的文本 */
    // 使用jQuery对象的each循环方法,这个方法专门用于循环伪数组
    // $btns.each(function () {
    //     // this是每个dom元素对象
    //    console.log(this.innerHTML)
    // });
    // 也可以为回调函数传递两个参数
    // $btns.each(function (index, item) {
    //     // 第一个参数是索引无需多说
    //     // 第二个参数取出来的是dom对象,可以直接点innerHTML取值
    //     // 也可以转为jQuery对象进行取值
    //     console.log(index, item.innerHTML, $(item).html());
    // });

    /* 示例4:输出"btn3"按钮是所有按钮中的第几个 */
    // index方法是返回当前元素在同级兄弟元素当中的索引位置,注意,兄弟元素也包括其他元素,如被注释的p元素也算元素,
    // 你可以取消p标签的注释,再运行下面的代码,它的索引位置就是3了
    // 但我们一般都是同类型标签中使用index,所以上面的p标签是个特例,毕竟ul中不搞li你搞其他标签也没啥意义是吧
    // 总之,index很实用
    console.log($("#btn3").index()); // 2  PS:索引从0开始
</script>
</body>
</html>

jQuery对象和dom对象相互转换

上面的例子中,用到了jQuery对象和dom对象的相互转换:

  • jQuery 对象 ==> dom对象:只要是获取标签对象时,拿到的伪数组中的每个元素对象都是dom对象,可以用来索引取值和遍历,如上面第2和第3个例子。
  • dom对象 ==> jQuery 对象:将dom对象作为参数传递给jQuery的核心函数,返回的结果就成了jQuery对象了,如$(this)和上例的上面的第3个示例中的$(item).html()

隐式遍历

需求,如下html中,点击每个div返回其内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>btn1</button>
<button>btn2</button>
<button>btn3</button>
    
<script src="jquery-1.11.3.min.js"></script>
<script>
    // 如果用原生js来实现的话,就要进行循环绑定
    // let btns = document.getElementsByTagName('button');
    // for (let i = 0; i < btns.length; i++) {
    //     // console.log(btns[i].innerHTML)
    //     btns[i].onclick = function () {
    //         console.log(this.innerHTML)
    //     }
    // }

    // 如果使用jQuery的话,就非常简单了
    $("button").click(function () {
        console.log($(this).html(), this.innerHTML);
    });
</script>
</body>
</html>

为啥使用jQuery就非常简单了?这是因为jQuery当中,对于操作元素的方法,都内置了隐式遍历。

隐式遍历都是用来进行统一操作的,因为隐式的关系,它不能在遍历期间进行其他操作,比如为标签内容是"btn3"的标签添加背景颜色。

jQuery元素选择器

基本选择器

没啥好说的,非常简单。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="div1" class="box">div1(class="box")</div>
<div id="div2" class="box">div2(class="box")</div>
<div id="div3">div3</div>
<span class="box">span(class="box")</span>
    
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
       1. 选择id为div1的元素
       2. 选择所有的div元素
       3. 选择所有class属性为box的元素
       4. 选择所有的div和span元素
       5. 选择所有class属性为box的div元素
    */
    // 1. 选择id为div1的元素
    // console.log($("#div1").html());

    // 2. 选择所有的div元素
    // console.log($("div").length); // 3

    // 3. 选择所有class属性为box的元素
    // $(".box").css('background', 'pink');

    // 4. 选择所有的div和span元素
    // $("div,span").css('background', 'pink');
    
    // 5. 选择所有class属性为box的div元素
    // $("div.box").css('background', 'pink');
</script>
</body>
</html>

组合选择器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
  <li>AAAAA</li>
  <li class="box">CCCCC</li>
  <li title="hello"><span>BBBBB</span></li>
  <li title="hello"><span>DDDD</span></li>
  <span>EEEEE</span>
</ul>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 选中ul下所有的的span
        2. 选中ul下所有的子元素span
        3. 选中class为box的下一个li
        4. 选中ul下的class为box的元素后面的所有兄弟元素
     */
    // 1. 选中ul下所有的的span
    // $("ul span").css('background', 'pink');

    // 2. 选中ul下所有的子元素span
    // $("ul>span").css('background', 'pink');

    // 3. 选中class为box的下一个li
    // $(".box + li").css('background', 'pink');

    // 4. 选中ul下的class为box的元素后面的所有兄弟元素
    // $(".box ~").css('background', 'pink');
</script>
</body>
</html>

过滤选择器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="div1" class="box">div1 id="div1" class="box"</div>
<div id="div2" class="box">div2 id="div2" class="box"</div>
<div id="div3">div3 id="div3"</div>
<span class="box">span class="box"</span>
<br/>
<ul>
    <li>AAAAAB</li>
    <li title="hello">BBBBB title="hello"</li>
    <li class="box">CCCCC class="box"</li>
    <li title="hello">DDDDDD title="hello"</li>
    <li title="two">BBBBB title="two"</li>
    <li style="display:none">我本来是隐藏的 style="display:none"</li>
</ul>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 选择第一个div
        2. 选择最后一个class为box的元素
        3. 选择所有class属性不为box的div
        4. 选择第二个和第三个li元素
        5. 选择内容为BBBBB的li
        6. 选择隐藏的li   可见性选择器
        7. 选择有title属性的li元素
        8. 选择所有属性title为hello的li元素
        9. 选择所有有title属性 且title属性不为hello的li元素
     */
    // 1. 选择第一个div
    // $("div:first").css('background', 'pink');

    // 2. 选择最后一个class为box的元素
    // $("div:last").css('background', 'pink');

    // 3. 选择所有class属性不为box的div
    // $("div:not(.box)").css('background', 'pink');

    // 4. 选择第二个和第三个li元素
    // 可以通过eq选择器来实现
    // 法1
    // $("li:eq(1)").css('background', 'pink');
    // $("li:eq(2)").css('background', 'pink');
    // 法2
    // $("li:eq(1),li:eq(2)").css('background', 'pink');
    // 法3 gt大于给定索引值;lt小于给定索引值 注意,gt和lt都不包含边界
    // 但实际结果会有三个标签背景变色,原因是,在jQuery中的选择器,是从左向右依次执行,每次的结果都是上一次筛选过的,再交给
    // 下一个选择器去执行,那么 $("li:gt(0):lt(3)").css('background', 'pink'); 这行代码执行的过程是这样的:
    /*
    * 第一步,$(li) 拿到所有li的伪数组
    *   [0, 1, 2, 3, 4, 5]
    * 然后执行gt(0),即把索引为0的元素删除掉,但后面的元素会往左移动得到新的伪数组
    *   [0, 1, 2, 3, 4]
    * 再对新的伪数组进行lt(3),即把索引大于2的删掉,得到新的伪数组
    *   [0, 1, 2]
    * 然后伪数组中的元素添加背景颜色,也就是我们看到的效果
    * */
    // $("li:gt(0):lt(3)").css('background', 'pink');
    // 怎么解决上面的问题呢?第一种方式如下
    // $("li:gt(0):lt(2)").css('background', 'pink');
    // 第二种方式,如下,就是先删除右边的,这样伪数组的元素位置没有发生向左移动的操作
    // $("li:lt(3):gt(0)").css('background', 'pink');

    // 5. 选择内容为BBBBB的li
    // $("li:contains(BBBBB)").css('background', 'pink');
    // 内容选择器,包含也算,即AAAAAB这样的也算
    // $("li:contains(B)").css('background', 'pink');

    // 6. 选择隐藏的li   可见性选择器
    // $("li:hidden").show(1000);

    // 7. 选择有title属性的li元素
    // $("li[title]").css('background', 'pink');

    // 8. 选择所有属性title为hello的li元素
    // $("li[title=hello]").css('background', 'pink');

    // 9. 选择所有有title属性 且title属性不为hello的li元素
    // 先找所有li,再过滤所有有title属性的,再过滤title属性不等于hello的
    // 下面两种方式都可以
    // $("li[title]:not([title=hello])").css('background', 'pink');
    // $("li[title][title!=hello]").css('background', 'pink');
</script>
</body>
</html>

表单选择器

jQuery封装了自己的表单元素选择器:input,它标签选择器input不太一样。

  • input标签选择器用于获取所有input标签。
  • jQuery的表单选择器:input可以获取所有表单元素::input:text:password:radio:checkbox:submit:image:reset:button:filehidden
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form>
  用户名: <input type="text"/><br>
  密 码: <input type="password"/><br>
  爱 好:
  <input type="checkbox" checked="checked" value="篮球"/>篮球
  <input type="checkbox" checked="checked"  />足球
  <input type="checkbox"  />羽毛球 <br>
  性 别:
  <input type="radio" name="sex" value='male'/>男
  <input type="radio" name="sex" value='female'/>女<br>
  邮 箱: <input type="text" name="email" disabled="disabled"/><br>
  所在地:
  <select>
    <option value="1" selected="selected">北京</option>
    <option value="2" >天津</option>
    <option value="3" >河北</option>
  </select><br>
  <input type="submit" value="提交"/>
</form>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 选择不可用的文本输入框
        2. 显示已选择的爱好的个数
        3. 显示选择的城市名称
     */
    // 1. 选择不可用的文本输入框
    // $(":text:disabled").css('background', 'pink');

    // 2. 显示已选择的爱好个数
    // console.log($(":checkbox:checked").length); // 2
    // console.log($(":checkbox:checked").size()); // 2

    // 3. 显示选择的城市名称
    // console.log($("select option:selected").val()); // 1
    // console.log($("select option:selected").html()); // 北京
</script>
</body>
</html>

工具方法

所谓的工具方法,这是人为起的名字,指的是jQuery封装好的一些方法,让我们当作工具来用,比如字符串去空格、序列化、遍历......

遍历

jQuery中有两个each方法用于遍历:

  • $.each,通用的遍历方法,通常用于遍历数组和对象,用的较多。该方法接受两个参数,第一个参数是要遍历的目标,第二参数是回调函数,回调函数也接受两个参数,如果遍历的对象,就是属性名称和属性值;如果遍历数组,就是索引和元素。
  • $().each,是专门用来遍历jQuery对象的。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li>AAAAA</li>
    <li>CCCCC</li>
    <li>BBBBB</li>
    <li>DDDDD</li>
</ul>

<script src="jquery-1.11.3.min.js"></script>
<script>
    // 先来看 $().each方法怎么用
    // 需求:输出所有li的内容
    // $("li").each(function () {
    //     console.log(this.innerHTML, $(this).html());
    // });
    // 也可以用$.each来做
    // $.each($('li'), function () {
    //     console.log(this.innerHTML, $(this).html())
    // })

    // 但$.each更为通用,通常用来遍历对象和数组
    let obj = {"name": "张开", "age": 18};
    let arr = ['a', 'b', 'c', 'd'];
    // $.each(obj, function (k, v) {
    //     console.log(k, v)
    // })
    $.each(arr, function (index, item) {
        console.log(index, item);
    })
</script>
</body>
</html>

其他常用工具方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="jquery-1.11.3.min.js"></script>
<script>
    let s = ' ab cd  ';
    let obj = {"name": "张开", "age": 18};
    let arr = ['a', 'b', 'c', 'd'];
    function fn() {}

    /*
    * 去除字符串两边的空格
    *   但我觉得, 还是js的去空格更为方便
    * */
    // console.log(s.trim()); // js去空格
    // console.log($.trim(s)); // jQuery去空格

    /*
    * 判断数据的类型
    * jQuery.type(true) === "boolean"
    * jQuery.type(3) === "number"
    * jQuery.type("test") === "string"
    * jQuery.type(function(){}) === "function"
    * jQuery.type([]) === "array"
    * jQuery.type(new Date()) === "date"
    * jQuery.type(/test/) === "regexp"
    * */
    // console.log($.type($)); // function
    // console.log($.type($())); // object
    // console.log($.type(obj)); // object
    // console.log($.type(arr)); // array

    /*
    * isArray 判断是否是数组
    * isFunction 判断是否是函数
    * */
    // console.log($.isArray(arr)); // true
    // console.log($.isFunction(fn)); // true
    // console.log($.isFunction($)); // true

    /*
    * 序列化
    *   序列化jQuery并没有封装相应的方法,所以,我们还是使用js的序列化方法
    *       JSON.stringify(obj)
    * 反序列化
    *   反序列化也可以使用js的,也可以使用jQuery的
    *       $.parseJSON(str) jQuery
    *       JSON.parse(str) js
    * */
    // 序列化
    let jsonObj = JSON.stringify(obj);
    let jsonArr = JSON.stringify(arr);
    console.log(jsonObj, $.type(jsonObj)); // {"name":"张开","age":18} string
    console.log(jsonArr, $.type(jsonArr)); // ["a","b","c","d"] string
    // 反序列化
    console.log($.parseJSON(jsonObj), $.type($.parseJSON(jsonObj))); // {"name": "张开", "age": 18} "object"
    console.log($.parseJSON(jsonArr), $.type($.parseJSON(jsonArr))); // ["a", "b", "c", "d"] "array"
</script>
</body>
</html>

通过上面去空格和序列化/反序列化的示例来看,在某些方面,jQuery倒不如原生的JavaScript的方法好用、简洁。

而jQuery的核心理念是write less,do more!更多是的对于JavaScript的进一步封装,觉得封装的不好用,那么用回JavaScript的即可。

总而言之,到底是使用jQuery还是JavaScript,要具体场景具体分析,哪个顺手用哪个即可!

属性操作

在jQuery中:

  • 操作任意属性

    • attr()
    • removeAttr()
    • prop(),它和attr的区别,attr用于操作属性值可以自定义的属性,比如id和class,他们的值我们可以随便定义;但对于属性值是固定的,比如值是bool类型的时候,就要用到prop方法了。
  • 操作class属性

    • addClass()
    • removeClass()
  • 操作HTML代码/文本/值

    • html()
    • val()

另外,jQuery当中的读写合一:

  • 单参数的方法,传值为写,不传值为读。
  • 双参数的方法,传两个值为写,传一个值为读。

因为jquery中的方法,内置隐试遍历,在我们设置内容的时候,不需要自己写遍历的语句。但是当你是一个读取操作时,如果用隐试遍历得话,读只读第一个,写是写所有。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="div1" class="box" title="one">div1 id="div1" class="box" title="one"</div>
<div id="div2" class="box" title="two">div2 id="div2" class="box" title="two"</div>
<div id="div3">div3 id="div3"</div>
<span class="box">span class="box"</span>
<br/>
<ul>
    <li>AAAAA</li>
    <li title="hello" class="box2">BBBBB title="hello" class="box2"</li>
    <li class="box">CCCCC class="box"</li>
    <li title="hello">DDDDDD title="hello"</li>
    <li title="two"><span>BBBBB title="two"</span></li>
</ul>

<input type="text" name="username" value="wangzhangkai"/>
<br>
<input type="checkbox">
<input type="checkbox">
<br>
<button>选中</button>
<button>不选中</button>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 读取第一个div的title属性
        2. 给所有的div设置name属性(value为zhangkai)
        3. 移除所有div的title属性
        4. 给所有的div设置class='wangzhangkai'
        5. 给所有的div添加class='abc'
        6. 移除所有div的class值:box
        7. 得到最后一个li的标签体文本
        8. 设置第一个li的标签体为"<h1>mmmmmmmmm</h1>"
        9. 得到输入框中的value值
        10. 将输入框的值设置为zhangkai
        11. 点击'全选'按钮实现全选
        12. 点击'全不选'按钮实现全不选
     */
    // 1. 读取第一个div的title属性
    // console.log($("div:first").attr('title')); // one

    // 2. 给所有的div设置name属性(value为zhangkai)
    // $("div").attr('name', 'zhangkai');

    // 3. 移除所有div的title属性
    // $("div").removeAttr('title');

    // 4. 给所有的div设置class='wangzhangkai'
    // 注意,使用attr设置class属性,算是一种重置操作,即原先class有值也都会覆盖掉
    // $("div").attr('class','wangzhangkai');

    // 5. 给所有的div添加class='abc'
    // addClass不会影响原有的class值,如果标签没有class,就添加;如果class存在就将值添加进去就完了,比attr的重置温柔一些
    // $("div").addClass('abc');

    // 6. 移除所有div的class值:box
    // $("div").removeClass('box');

    // 7. 得到最后一个li的标签体文本
    // console.log($("li:last").html()); // <span>BBBBB title="two"</span>

    // 8. 设置第一个li的标签体为"<h1>mmmmmmmmm</h1>"
    // $("li:first").html("<h1>mmmmmmmmm</h1>");

    // 9. 得到输入框中的value值
    // console.log($("input:text").val()); // wangzhangkai
    // console.log($(":text").val()); // wangzhangkai


    // 10. 将输入框的值设置为zhangkai
    // $("input:text").val("zhangkai");

    // 11. 点击'全选'按钮实现全选
    $("button:first").click(function () {
        $("input:checkbox").prop('checked', true);
    });

    // 12. 点击'全不选'按钮实现全不选
    $("button:last").click(function () {
        $("input:checkbox").prop('checked', false);
    });
</script>
</body>
</html>

CSS操作

css方法不受只能读取行内样式的限制,只要这个标签有css,它都能读取到。

css方法设置单个样式,直接以属性、属性值的形式设置即可;如果同时设置多个值,就以对象的形式设置。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .test{
            color: blue;
        }
    </style>
</head>
<body>
<p class="test">p1 class="test" style="color: blue;"</p>
<p style="color: green;">p2 style="color: green;"</p>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 得到第一个p标签的颜色
        2. 设置所有p标签的文本颜色为pink
        3. 设置第2个p的字体颜色(#ff0011),背景(blue),宽(300px), 高(30px)
     */
    // 1. 得到第一个p标签的颜色
    console.log($("p:first").css('color')); // rgb(0, 0, 255)

    // 2. 设置所有p标签的文本颜色为pink
    // $("p").css('color', 'pink');

    // 3. 设置第2个p的字体颜色(#ff0011),背景(blue),宽(300px), 高(30px)
    $("p:last").css({
        "color": "#ff0011",
        "background": "blue",
        "width": "300px",
        "height": "30px"
    });
</script>
</body>
</html>

offset和position

在定位中,offset方法返回的是一个对象,包含left和top两个属性,这两个属性标识元素相对于页面左上角的位置。

position方法返回的是一个对象,包含left和top两个属性,这两个属性标识元素相对于"包含块"左上角的位置。

注意,offset和position返回的对象中的两个属性值都是不带单位的数值,但单位是像素。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        .div1 {
            position: absolute;
            width: 200px;
            height: 200px;
            top: 20px;
            left: 10px;
            background: blue;
            /* display,元素不可见 */
            /*display: none;*/
            /* visibility占位隐藏,但元素还在 */
            /*visibility: hidden;*/
        }

        .div2 {
            position: absolute;
            width: 100px;
            height: 100px;
            top: 50px;
            background: red;
        }

        .div3 {
            position: absolute;
            width: 50px;
            height: 50px;
            background: pink;
            left: 0;
            top: 50px;
        }
    </style>
</head>
<body style="height: 2000px;">
<div class="div1">
    <div class="div2">
        <!--<div class="div3"></div>-->
    </div>
</div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. 打印 div1 相对于页面左上角的位置
        2. 打印 div2 相对于页面左上角的位置
        3. 打印 div1 相对于父元素左上角的位置
        4. 打印 div2 相对于父元素左上角的位置
    */
    // 1. 打印 div1 相对于页面左上角的位置
    console.log($(".div1").offset()); // {top: 20, left: 10}

    // 2. 打印 div2 相对于页面左上角的位置
    console.log($(".div2").offset()); // {top: 70, left: 10}

    // 3. 打印 div1 相对于父元素左上角的位置
    console.log($(".div1").position()); // {top: 20, left: 10}

    // 4. 打印 div2 相对于父元素左上角的位置
    console.log($(".div2").position()); // {top: 50, left: 0}
</script>
</body>
</html>

上面关于position方法的描述中的"包含块"这里还有点需要进一步解释的,看下面的示例。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        .div1 {
            position: absolute;
            width: 200px;
            height: 200px;
            top: 20px;
            left: 10px;
            background: blue;
            /* display,元素不可见 */
            /*display: none;*/
            /* visibility占位隐藏,但元素还在 */
            /*visibility: hidden;*/
            /*溢出隐藏*/
            /*overflow: hidden;*/
        }

        .div2 {
            /*position: absolute;*/
            width: 100px;
            height: 100px;
            top: 50px;
            background: red;
            margin-top: 30px;
        }

        .div3 {
            position: absolute;
            width: 50px;
            height: 50px;
            background: pink;
            left: 0;
            top: 50px;
        }
    </style>
</head>
<body style="height: 2000px;">
<div class="div1">
    <div class="div2">
        <div class="div3"></div>
    </div>
</div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /*
    * 将div2的定位关闭,并给个margin-top: 30px;来搞个样式
    * 那么div3的定位位置就跟着div1走了,所以div1算是div3的包含块
    * 但这个例子是特例,一般子元素设置了定位后,它的父元素也会开启定位
    * */
    console.log($(".div3").position()); // {top: 50, left: 0}
</script>
</body>
</html>

由上例的返回结果和页面显示的效果可以证明,子元素的开启定位后,它按照父级标签或者祖辈标签(一层层往上找)设置了相对定位的标签位置进行移动,如果这些(父、祖辈)标签都没有设置相对定位,那么就以整个文档的位置进行移动。且当前标签将脱离文档流。

所以,包含块一般是指的是父级标签(毕竟一般都这么干,上面的是特殊例子),但像上面的例子中,就比较特殊,直属父级标签没有开启定位,而是爷爷标签开启了定位,那它就跟着爷爷走了....

另外,offset和position只对可见元素有效,对于display: none这种的就没效了,如下示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        .div1 {
            position: absolute;
            width: 200px;
            height: 200px;
            top: 20px;
            left: 10px;
            background: blue;
            /* display,元素不可见 */
            display: none;
            /* visibility占位隐藏,但元素还在 */
            /*visibility: hidden;*/
        }

        .div2 {
            position: absolute;
            width: 100px;
            height: 100px;
            top: 50px;
            background: red;
            margin-top: 30px;
        }

        .div3 {
            position: absolute;
            width: 50px;
            height: 50px;
            background: pink;
            left: 0;
            top: 50px;
        }
    </style>
</head>
<body style="height: 2000px;">
<div class="div1">
    <div class="div2">
        <div class="div3"></div>
    </div>
</div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    // 1. 打印 div1 相对于页面左上角的位置
    console.log($(".div1").offset()); // {top: 0, left: 0}

    // 2. 打印 div2 相对于页面左上角的位置
    console.log($(".div2").offset()); // {top: 0, left: 0}

    // 3. 打印 div1 相对于父元素左上角的位置
    console.log($(".div1").position()); // {top: 0, left: 0}

    // 4. 打印 div2 相对于父元素左上角的位置
    console.log($(".div2").position()); // {top: -30, left: 0}  这个-30是margin-top: 30px;
</script>
</body>
</html>

总的来说,jQuery提供的offset和position并没有比原生JavaScript好用到哪去。

元素滚动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body style="height: 2000px;">
<div class="box" style="border:1px solid black;width:100px;height:150px;overflow:auto">
    This is some text. This is some text. This is some text. This is some text.
    This is some text. This is some text. This is some text. This is some text.
    This is some text. This is some text. This is some text. This is some text.
    This is some text. This is some text. This is some text. This is some text.
    This is some text. This is some text. This is some text. This is some text.
    This is some text. This is some text. This is some text. This is some text.
    his is some text.
</div>
<br>
<br>
<br>
<button id="btn1">得到scrollTop</button>
<button id="btn2">设置scrollTop</button>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
       1. 得到div或页面滚动条的坐标
       2. 让div或页面的滚动条滚动到指定位置
    */
    //
    $("#btn1").click(function () {
        // 1. 得到div或页面滚动条的坐标
        // console.log($(".box").scrollTop());
        /*
        * 这里扩展的说下操作页面的滚动条,操作页面的滚动条,可以通过 html body document 这三种方式
        * 先说通过html和body获取页面滚动条
        *   早些时候,这二者是互斥的:
        *       即有的浏览器通过html能获取到值,那么通过body获取的值为0,如chrome浏览器
        *       有的浏览器能通过body获取到值,通过html获取的值就为0.如edge浏览器
        *   但后来edge也用了chrome的内核了,它俩就没啥差别了
        *   所以,现在记住,想要获取页面的滚动,直接使用html来做。
        * 最后,再来说通过document来获取页面的滚动条,也正常获取。
        * */
        // console.log($('body').scrollTop());
        // console.log($('html').scrollTop());
        // console.log($(document).scrollTop());
    });
    
    // 2. 让div或页面的滚动条滚动到指定位置
    $("#btn2").click(function () {
        // 设置的话,直接跟数值就好了,不要带单位,也不要传个负数
        $(".box").scrollTop(200);
        // 至于页面的滚动条设置,通过html和document都行
        $(document).scrollTop(50);
    });
</script>
</body>
</html>

上面的例子只是说了scrollTop,而scrollLeft的操作是一样的,而且scrollLeft将来用的比较少了,所以就不单独举例子了。

筛选过滤方法

在jQuery选择器部分讲过过滤选择器,这一小节我们来研究过滤筛选方法,这俩有啥区别呢:

  • 过滤选择器,是在元素查询阶段,传入到jQuery核心函数当中,当作匹配元素的规则。
  • 过滤筛选方法,是在已经有jQuery对象的前提下,我们想要对这个先有的jQuery对象里面的元素进行筛选。常用方法有这些:
    • first():第一个。
    • last():最后一个。
    • eq(index/-index),根据索引过滤元素。
    • filter(selector),根据传入的选择器过滤元素。
    • not(selector):取反。
    • has(selector):具有。
    • children():子标签中找。
    • find():后代标签(包括子标签)中找。
    • parent():父标签。
    • prevAll([selector])/nextAll([selector]):前面/后面所有兄弟标签,可以传入选择器。
    • prev()/next():前面/后面一个兄弟标签,不可以传入选择器。
    • siblings():同级别的所有兄弟标签。

示例1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
  <li>AAAAA</li>
  <li title="hello" class="box2">BBBBB</li>
  <li class="box">CCCCC</li>
  <li title="hello" class="item">DDDDDD</li>
  <li title="two"><span class="test">BBBBB</span></li>
</ul>
<li>eeeee</li>
<li>EEEEE</li>
<br>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. ul下li标签第一个
        2. ul下li标签的最后一个
        3. ul下li标签的第二个
        4. ul下li标签中title属性为hello的
        5. ul下li标签中title属性不为hello的
        6. ul下li标签中有span子标签的
    */
    // 首先获取所有的元素。
    let $arr = $("ul li");
    // console.log($arr);

    // 1. ul下li标签第一个
    // $arr.first().css('background', 'pink');

    // 2. ul下li标签的最后一个
    // $arr.last().css('background', 'pink');

    // 3. ul下li标签的第二个
    // 索引从左往右从0开始,从右往左是从-1开始
    // $arr.eq(1).css('background', 'pink');
    // $arr.eq(-4).css('background', 'pink');

    // 4. ul下li标签中title属性为hello的
    // $arr.filter("[title=hello]").css('background', 'pink');

    // 5. ul下li标签中title属性不为hello的
    // $arr.filter("[title!=hello]").css('background', 'pink');
    // $arr.not("[title=hello]").css('background', 'pink');

    // 6. ul下li标签中有span子标签的
    // $arr.has('span').css('background', 'pink');
</script>
</body>
</html>

示例2,查找孩子、父级标签、兄弟标签。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="div1" class="box" title="one">class为box的div1 id="div1" class="box" title="one"</div>
<div id="div2" class="box">class为box的div2 id="div2" class="box"</div>
<div id="div3">div3 id="div3"</div>
<span class="box">class为box的span class="box"</span>
<br/>
<div>
  <ul>
    <span>span文本1</span>
    <li>AAAAA</li>
    <li title="hello" class="box2">BBBBB title="hello" class="box2"</li>
    <li class="box" id='cc'>CCCCC class="box" id='cc'</li>
    <li title="hello">DDDDDD title="hello"</li>
    <li title="two"><span>span文本2 title="two"</span></li>
    <span>span文本3</span>
  </ul>
  <span>span文本444</span><br>
  <li>eeeee</li>
  <li>EEEEE</li>
  <br>
</div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
        1. ul标签的第2个span子标签
        2. ul标签的第2个span后代标签
        3. ul标签的父标签
        4. id为cc的li标签的前面的所有li标签
        5. id为cc的li标签的所有兄弟li标签
    */
    // 先找到一个元素作为定位起始位置。
    let $ul = $("ul");

    // 1. ul标签的第2个span子标签
    // $ul.children("span:eq(1)").css('background', 'pink');

    // 2. ul标签的第2个span后代标签
    // $ul.find("span:eq(1)").css('background', 'pink');

    // 3. ul标签的父标签
    // $ul.parent().css('background', 'pink');

    // 4. id为cc的li标签的前面的所有li标签
    // prevAll/nextAll: 前面/后面所有,可以传入选择器
    // $("#cc").prevAll('li').css('background', 'pink');
    // $("#cc").nextAll('li').css('background', 'pink');
    // prev/next:前面/后面一个,不可以传入选择器
    // $("#cc").prev().css('background', 'pink');
    // $("#cc").next().css('background', 'pink');

    // 5. id为cc的li标签的所有兄弟li标签
    // $("#cc").siblings("li").css('background', 'pink');
</script>
</body>
</html>

元素尺寸

来看怎么获取元素的尺寸。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div {
            width: 100px;
            height: 150px;
            background: red;
            padding: 11px;
            border: 11px #fbd850 solid;
            margin: 10px;
        }
    </style>
</head>
<body>
<div>div</div>
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    let $div = $("div");
    // 内容尺寸,即获取标签的width和height
    console.log($div.width(), $div.height()); // 100 150

    // 内部尺寸,指的是width+padding/height+padding
    console.log($div.innerWidth(), $div.innerHeight()); // 122 172

    /*
    * 外部尺寸,通过outerWidth/outerHeight来获取,这两个方法接收布尔值,且默认值为false,有两种情况,以宽为例,当:
    *   outerWidth(false):获取的是 width+padding+border
    *   outerWidth(true):获取的是 width+padding+border+margin
    * 高同理,不在多表
    * */
    console.log($div.outerWidth(), $div.outerHeight()); // 144 194
    console.log($div.outerWidth(true), $div.outerHeight(true)); // 164 214
</script>
</body>
</html>

文档的增删改查

添加文档:

  • 内部插入,将文档插入到指定元素的内部。
    • 添加到所有子元素的最后,append/appendTo,这俩方法功能一样。
    • 添加到所有子元素的最前面,prepend/perpendTo,这俩方法功能一样。
  • 外部插入,将文档插入指定元素的前面/后面。
    • before/after,没啥好说的了。

替换文档,选择要替换的文档,使用replaceWith进行替换就行了。

删除文档:

  • remove删除选择的元素。
  • empty,清空选择的元素。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="ul1">
    <li>AAAAA</li>
    <li title="hello">BBBBB</li>
    <li class="box">CCCCC</li>
    <li title="hello">DDDDDD</li>
    <li title="two">EEEEE</li>
    <li>FFFFF</li>
</ul>
<br>
<ul id="ul2">
    <li class="re">aaa</li>
    <li title="hello">bbb</li>
    <li class="box">ccc</li>
    <li title="hello">ddd</li>
    <li title="two">eee</li>
</ul>
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
         1. 向id为ul1的ul下添加一个span(最后)
         2. 向id为ul1的ul下添加一个span(最前)
         3. 在id为ul1的ul下的li(title为hello)的前面添加span
         4. 在id为ul1的ul下的li(title为hello)的后面添加span
         5. 将在id为ul2的ul下的li(title为hello)全部替换为p
         6. 移除id为ul2的ul下的所有li
    */
    // 1. 向id为ul1的ul下添加一个span(最后)
    // $("#ul1").append("<span>我是 append 添加的span</span>");
    // $("<span>我是 appendTo 添加的span</span>").appendTo("#ul1");

    // 2. 向id为ul1的ul下添加一个span(最前)
    // $("#ul1").prepend("<span>我是 prepend 添加的span</span>");
    // $("<span>我是 prependTo 添加的span</span>").prependTo("#ul1");

    // 3. 在id为ul1的ul下的li(title为hello)的前面添加span
    // $("#ul1 li[title=hello]").before("<span>我是 before 添加的span</span>");

    // 4. 在id为ul1的ul下的li(title为hello)的后面添加span
    // $("#ul1 li[title=hello]").after("<span>我是 after 添加的span</span>");

    // 5. 将在id为ul2的ul下的li(title为hello)全部替换为p
    // $("#ul2 li[title=hello]").replaceWith("<p>我是替换的p标签</p>");

    // 6. 移除id为ul2的ul下的所有li
    // $("#ul2 li").remove();
    // $("#ul2").empty();
</script>
</body>
</html>

事件

事件的绑定与解绑

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        * {
            margin: 0;
        }

        .out {
            position: absolute;
            width: 200px;
            height: 200px;
            top: 20px;
            left: 10px;
            background: pink;
        }

        .inner {
            position: absolute;
            width: 100px;
            height: 100px;
            top: 50px;
            background: skyblue;
        }

        .divBtn {
            position: absolute;
            top: 250px;
        }

    </style>
</head>
<body>
<div class="out">
    外部DIV
    <div class="inner">内部div</div>
</div>
<div class='divBtn'>
    <button id="btn1">取消绑定所有事件</button>
    <button id="btn2">取消绑定mouseover事件</button>

</div>
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
         1. 给.out绑定点击监听(用两种方法绑定)
         2. 给.inner绑定鼠标移入和移出的事件监听(用3种方法绑定)
         3. 点击btn2解除.out上的mouseleave事件
         4. 点击btn1解除.out上的所有事件监听
    */
    // 1. 给.out绑定点击监听(用两种方法绑定)
    // 法1,直接通过对象点事件名称,特点就是可以重复绑定
    // $(".out").click(function () {
    //     console.log('点击我了1');
    // });
    // $(".out").click(function () {
    //     console.log('点击我了2');
    // });

    /*
    * 法2,通过on来绑定,用法是
    *   $(".out").on(事件类型, 回调函数);
    * on的特点就是可以通过是绑定多个类型的事件,然后共同调用一个回调函数,但用的较少
    * */
    // 基本用法,也是常用的方式
    // $(".out").on('click', function () {
    //     console.log('点击我了');
    // });
    // 多个事件共用一个回调函数,用的不多
    // $(".out").on('click mouseleave', function () {
    //     console.log('点击我了');
    // });

    // 2. 给.out绑定鼠标移入和移出的事件监听(用3种方法绑定)
    // 可以用onmouseenter/onmouseleave实现
    // $(".out").mouseenter(function () {
    //     console.log('移入');
    // });
    // $(".out").mouseleave(function () {
    //     console.log('移出');
    // });

    // 上面的两个事件可以写成链式事件
    // $(".out").mouseenter(function () {
    //     console.log('移入');
    // }).mouseleave(function () {
    //     console.log('移出');
    // });

    // 再补充一个hover,其实这个家伙底层也是用onmouseenter/onmouseleave实现的
    // 就是为了简化代码,没别的意思
    // $(".out").hover(function () {
    //     console.log('移入');
    // },function () {
    //     console.log('移出');
    // });

    // 如果只为hover传递一个回调函数,那么移入移出都走这一个回调函数
    // $(".out").hover(function () {
    //    console.log('移入移出都走我!!!');
    // });

    // 3. 点击btn2解除.out上的mouseleave事件
    // $("#btn2").click(function () {
    //     // off如果不传递参数,默认清除所有事件
    //     // 传递参数的话, 以字符串的形式传递要清除的一个或多个事件,事件之间用空格隔开
    //     $(".out").off("mouseenter mouseleave");
    // });

    // 4. 点击btn1解除.out上的所有事件监听
    // $("#btn1").click(function () {
    //     // off如果不传递参数,默认清除所有事件
    //     $(".out").off();
    // });
</script>
</body>
</html>

事件委派

事件委派(也叫委托)基于事件冒泡的机制将子元素的事件统一的绑定给父级元素(也可以是祖先元素)。子元素触发事件时,会冒泡给父级元素,在父级元素的回调函数中,处理子元素的逻辑。

事件委派的好处:

  • 对于新添加的子元素,自动有事件响应处理。
  • 减少事件监听的数量。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li>AAAA</li>
    <li>BBBB</li>
    <li>CCCC</li>
    <li>DDDD</li>
</ul>
<br>
<button id="btn1">事件委派:点我添加新的li</button>
<button id="btn2">事件委派:点我解绑</button>
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    $("#btn1").click(function () {
        $("ul").append("<li>我是新的li标签</li>");
    });

    /*
        引入: 绑定监听事件的问题,新添加的元素没有监听到
    */
    // $("ul li").click(function () {
    //     // this.style.background = "pink";
    //     $(this).css('background', 'pink');
    // });

    // jQuery实现的事件委派,有两个方法实现事件委派,这俩方法没啥区别,只是绑定方式不同
    // 法1 delegate
    // delegate(子元素,事件, 回调函数)
    // $("ul").delegate('li', 'click', function () {
    //     $(this).css('background', 'pink');
    // });

    // 法2, 通过父级标签调用on(事件, 子元素, 回调函数)方法
    $("ul").on('click', 'li', function () {
        $(this).css('background', 'pink');
    });

    // 解绑事件委派的事件
    $("#btn2").click(function () {
        // 可以用jQuery专门提供的解绑方法,不用传参数
        // $("ul").undelegate();

        // 也可以用通用的取消事件的off来做
        $("ul").off();
    });
</script>
</body>
</html>

注意,绑定的标签必须是唯一的,否则委派失败,比如上例,通过jQuery对ul进行绑定on事件,然后委派给其内的子元素li触发,但如果ul不是是唯一的,仍然会绑定失败
在jQuery1.7之前还有个live方法能实现事件委派,但1.7之后就被删除了,所以就不用记了。

window.onload和$(document).ready的区别

window.onload是等页面加载完成并渲染完成,包括外部资源也加载完成,才会执行回调函数。

而jQuery提供的$(document).ready方法,它是在dom加载完成后,就会执行,所以等待的资源更少,执行要比window.onload要快,但遇到外部资源没加载完成这种问题,就无能为力了。

除此之外,window.onload就算多次声明,也只会覆盖;而$(document).ready可以多次执行。

因为浏览器会缓存图片,所以,下面的的代码重复运行的话,要记得清除缓存。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>测试window.onload与$(document).ready()的区别</h1>
<img id="logo" src="https://www.baidu.com/img/flexible/logo/pc/result.png">
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    let $img = $("#logo");
    console.log("默认: ", $img.width());

    // window.onload,多次声明不会重复执行
    window.onload = function () {
        console.log("window.onload 1: ", $img.width());
    };

    window.onload = function () {
        console.log("window.onload 2: ", $img.width());
    };

    // $(document).ready
    $(document).ready(function () {
        console.log("$(document).ready 1: ", $img.width());
    });

    // $(document).ready 的简写形式如下
    $(function () {
        console.log("$(document).ready 2: ", $img.width());
    })
</script>
</body>
</html>

动画

主要介绍淡出淡出和切换。

实现原理就是通过不断改变元素的透明度来实现显示和隐藏。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #d1{
            width: 200px;
            height: 200px;
            background-color: red;
            margin-top: 20px;
        }
    </style>
</head>
<body>
<div>
    <button id="btn1">慢慢淡出</button>
    <button id="btn2">慢慢淡入</button>
    <button id="btn3">淡入淡出切换</button>
</div>
<div id="d1"></div>

<script src="jquery-1.11.3.min.js"></script>
<script>
    // 淡出
    $("#btn1").click(function () {
        $("#d1").fadeOut(1000);  // 单位毫秒,也可以不传
    });

    // 淡出
    $("#btn2").click(function () {
        $("#d1").fadeIn(1000);  // 单位毫秒,也可以不传
    });

    // 淡出
    $("#btn3").click(function () {
        $("#d1").fadeToggle(1000);  // 单位毫秒,也可以不传
    });
</script>
</body>
</html>

扩展插件

有的时候,jQuery提供的方法可能不多,或者我们一些自定义的功能想要通过jQuery来调用,相当于扩展jQuery,这里我们叫做扩展插件。来看看怎么搞,有两种方式:

  • 扩展jQuery的工具方法,也就是扩展通过$函数直接调用的方法。
  • 扩展jQuery对象的方法,也就是扩展通过$对象调用的方法。

先来看如何扩展jQuery的工具方法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="jquery-1.11.3.min.js"></script>
<script>
    // 举个例子,jQuery函数本身并没有min和max方法
    // console.log($.min, $.max); // undefined undefined
    // 我们就通过为它添加min和max这两个方法来演示
    // 使用$.extend(object)进行扩展,参数传个对象,在对象中写扩展插件
    $.extend({ // 如果扩展插件比较复杂,比较多的话,可以单独写到一个js文件中,引入时放到jQuery文件下面即可
        min: function (a, b) {
            return a > b ? b : a;
        },
        max: function (a, b) {
            return a > b ? a : b;
        }
    });
    // 然后就可以直接调用了
    console.log($.min(3, 2)); // 2
    console.log($.max(3, 2)); // 3
</script>
</body>
</html>

再来看扩展jQuery对象的方法的示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>篮球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球
<br/>
<input type="button" id="btn1" value="全 选"/>
<input type="button" id="btn2" value="全不选"/>
<input type="button" id="btn3" value="反 选"/>
<script src="jquery-1.11.3.min.js"></script>
<script>
    // 举个例子,为jQuery对象添加下面三个方法
    // checkAll() 全选
    // reverseCheck() 反选
    // unCheckAll() 全不选

    // 使用$.fn.extend(object)进行扩展,参数传个对象,在对象中写扩展插件
    $.fn.extend({ // 如果扩展插件比较复杂,比较多的话,可以单独写到一个js文件中,引入时放到jQuery文件下面即可
        checkAll: function () {
            // 在方法内部,this指向当前调用这个方法的对象,
            // 此处为调用checkAll方法的复选框数组,它是一个jQuery对象
            this.prop('checked', true);
        },
        reverseCheck: function () {
            this.each(function () {
                this.checked = !this.checked;
            })
        },
        unCheckAll: function () {
            this.prop('checked', false);
        }
    });
    // 然后就可以直接调用了
    let $checkArr = $(":checkbox");

    // 全选
    $("#btn1").click(function () {
        $checkArr.checkAll();
    });

    // 全不选
    $("#btn2").click(function () {
        $checkArr.unCheckAll();
    });

    // 反选
    $("#btn3").click(function () {
        $checkArr.reverseCheck();
    });
</script>
</body>
</html>

多库共存

所谓的多库共存,指的是,当$符号,被别的js文件占用了,那么jQuery就要释放$的使用权这么个不常见的场景。

比如,有个js文件,内容:

(function (window) {
    window.$ = function () {
        console.log('我是mylib中的$')
    }
});

html代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="myLib.js"></script>
<script src="jquery-1.11.3.min.js"></script>
<script>
    // 如上面两个js文件,都有对$的定义,这就有冲突了,那么默认的,谁在下面,谁生效
    // 想解决冲突,可以使用jQuery提供的noConflict方法来解决冲突。那么,noConflict做了什么呢?
    // 当$发生命名冲突时,优先加载jQuery,然后调用noConflict方法,就可以让jQuery释放掉对于$的使用权了
    // 但是此后,想要jQuery,就用使用全称 jQuery 了

    // 用法如下,先释放$
    jQuery.noConflict();

    // 这个时候,$就是别人的了
    $();

    // 想要用jQuery就需要要使用全称
    jQuery(function () {
        console.log('我是jQuery');
    });
</script>
</body>
</html>

示例

爱好选择器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form>
    你爱好的运动是?<input type="checkbox" id="checkedAllBox"/>全选/全不选

    <br/>
    <input type="checkbox" name="items" value="足球"/>足球
    <input type="checkbox" name="items" value="篮球"/>篮球
    <input type="checkbox" name="items" value="羽毛球"/>羽毛球
    <input type="checkbox" name="items" value="乒乓球"/>乒乓球
    <br/>
    <input type="button" id="checkedAllBtn" value="全 选"/>
    <input type="button" id="checkedNoBtn" value="全不选"/>
    <input type="button" id="checkedRevBtn" value="反 选"/>
    <input type="button" id="sendBtn" value="提 交"/>
</form>

<script src="jquery-1.11.3.min.js"></script>
<script>
    /* 需求:
       1. 点击'全选': 选中所有爱好
       2. 点击'全不选': 所有爱好都不勾选
       3. 点击'反选': 改变所有爱好的勾选状态
       4. 点击'全选/全不选': 选中所有爱好, 或者全不选中
       5. 点击某个爱好时, 必要时更新'全选/全不选'的选中状态
       6. 点击'提交': alert提示所有勾选的爱好
    */
    let $checkedAllBtn = $("#checkedAllBtn"); // 全选按钮
    let $checkedNoBtn = $("#checkedNoBtn");  // 全不选按钮
    let $checkedAllBox = $("#checkedAllBox"); // 全选/全不选按钮
    let $checkedRevBtn = $("#checkedRevBtn"); // 反选按钮
    let $sendBtn = $("#sendBtn"); // 提交按钮
    let $hobbies = $(":checkbox[name=items]");  // 所有爱好数组

    // 1. 点击'全选': 选中所有爱好
    $checkedAllBtn.click(function () {
        // 让所有爱好都勾选
        $hobbies.prop('checked', true);
        // 让全选/全不选按钮也勾选
        $checkedAllBox.prop('checked', true);
    });

    // 2. 点击'全不选': 所有爱好都不勾选
    $checkedNoBtn.click(function () {
        // 取消所有爱好的勾选
        $hobbies.prop('checked', false);
        // 取消全选/全不选按钮的勾选
        $checkedAllBox.prop('checked', false);
    });

    // 3. 点击'反选': 改变所有爱好的勾选状态
    $checkedRevBtn.click(function () {
        // 需要通过判断每个复选框当前的状态来切换,所以要自己循环,隐式遍历不好使了
        $hobbies.each(function () {
            // 感叹号取反,然后将值设置给当前的复选框
            this.checked = !this.checked;

            // 注意,如果所有的复选框都勾选了,即处于全选状态,那么全选/全不选按钮也要勾上
            // 这个逻辑我们有三种处理方式
            // 法1,思路是,如果选中的复选框的数量等于所有复选框的个数,说明是全选状态,选/全不选按钮要勾上,否则取消勾选
            // if ($hobbies.filter(":checked").length === $hobbies.length) {
            //     $checkedAllBox.prop('checked', true);
            // }else {
            //     $checkedAllBox.prop('checked', false);
            // }

            // 法2,如果通过判断一个表达式是否成立来设置一个布尔值的结果,那么可以直接将表达式设置在布尔值的位置上
            // $checkedAllBox.prop('checked', $hobbies.filter(":checked").length === $hobbies.length);

            // 法3,思想是,不选中的个数为0,则说明是全选
            $checkedAllBox.prop('checked', $hobbies.filter(":not(:checked)").length === 0);
        });
    });

    // 4. 点击'全选/全不选': 选中所有爱好, 或者全不选中
    $checkedAllBox.click(function () {
        $hobbies.prop('checked', this.checked);
    });

    // 5. 点击某个爱好时, 必要时更新'全选/全不选'的选中状态
    $hobbies.click(function () {
        $checkedAllBox.prop('checked', $hobbies.filter(":not(:checked)").length === 0);
    });

    // 6. 点击'提交': alert提示所有勾选的爱好
    $sendBtn.click(function () {
        // 循环alert最新选中的爱好值
        if ($hobbies.filter(":checked").length === 0) {
            alert('至少要勾选一个爱好!!!')
        } else {
            $hobbies.filter(":checked").each(function () {
                alert(this.value);
            });
        }
    });
</script>
</body>
</html>

table标签切换

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #tab li {
            float: left;
            list-style: none;
            width: 80px;
            height: 40px;
            line-height: 40px;
            cursor: pointer;
            text-align: center;
        }

        #container {
            position: relative;
        }

        #content1, #content2, #content3 {
            width: 300px;
            height: 100px;
            padding: 30px;
            position: absolute;
            top: 40px;
            left: 0;
        }

        #tab1, #content1 {
            background-color: #ffcc00;
        }

        #tab2, #content2 {
            background-color: #ff00cc;
        }

        #tab3, #content3 {
            background-color: #00ccff;
        }
    </style>
</head>
<body>
<h2>多Tab点击切换</h2>
<ul id="tab">
    <li id="tab1" value="1">10元套餐</li>
    <li id="tab2" value="2">30元套餐</li>
    <li id="tab3" value="3">50元包月</li>
</ul>
<div id="container">
    <div id="content1">
        10元套餐详情:<br/>&nbsp;每月套餐内拨打100分钟,超出部分2毛/分钟
    </div>
    <div id="content2" style="display: none">
        30元套餐详情:<br/>&nbsp;每月套餐内拨打300分钟,超出部分1.5毛/分钟
    </div>
    <div id="content3" style="display: none">
        50元包月详情:<br/>&nbsp;每月无限量随心打
    </div>
</div>
<br>
<script src="jquery-1.11.3.min.js"></script>
<script>
    let $li = $("ul li");
    let $divs = $("#container div");
    $li.click(function () {
        let index = $(this).index();
        $divs.eq(index).show().siblings().hide();
    });
</script>
</body>
</html>

比较日期

针对于比较日期的情况,例如结束日期不能小于开始日期这种情况,我们就需要判断两个日期的大小来决定了,所以,可以用下面的方式进行比较。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
<label for="startTime">开始日期</label>
<input type="date" id="startTime" name="startTime">
<br>
<label for="endTime">结束日期</label>
<input type="date" id="endTime" name="endTime">
<span id="msg"></span>
</body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
    $("#endTime").change(function () {
        let startTime = $("#startTime").val();
        let endTime = $("#endTime").val();
        // console.log(11, startTime, endTime)
        if (new Date(endTime) > new Date(startTime)){
            $("#msg").text(`结束日期${endTime} 大于 开始日期${startTime},合法!!!`);
            $("#msg").css("color", 'green');
        }else {
            $("#msg").text(`结束日期${endTime} 不大于 开始日期${startTime}, 不合法!!`);
            $("#msg").css("color", 'red')
        }
    })
</script>
</html>

posted @ 2018-08-31 00:50  听雨危楼  阅读(162)  评论(0编辑  收藏  举报