jQuery基础

1. 初识jQuery

需求:点击‘确定’按钮,输入提示的值

用户名: <input type="text" id="username">
<button id="btn1">确定(原生版)</button>
<button id="btn2">确定(jQuery版)</button>

方式一:使用原生的js实现功能

  <script type="text/javascript">
    window.onload = function () {
      var btn = document.getElementById('btn1')
      btn.onclick = function () {
        alert(document.getElementById('username').value)
      }
    }
  </script>

方式二:使用jQuery 版本3.5.1

 //绑定文档加载完成的监听
    $(function(){
      $('#btn2').click(function(){
        const username = $('#username').val();
        alert(username);
      });
    });

效果:

image-20201009222118621

点击原生:

image-20201009222201889

点击jQuery:

image-20201009222213861

2. jQuery的两把利器

jQuery的核心函数介绍

简称:jQuery函数($/jQuery),jQuery库向外直接暴露的就是$/jQuery,引入jQuery库后,直接使用$即可。

部分源码(版本1.10.1):

image-20201009222601804

jQuery的核心对象介绍

简称:jQuery对象.执行jQuery函数返回的就是jQuery对象,使用jQuery对象:$obj.xxx()

代码如下:

  console.log(typeof $)   //$是一个function
  console.log($ === jQuery) //true  $与jQuery等同
  console.log($ === window.$) //true  $是一个全局函数
  console.log(typeof $()) //"object"  这个对象就是jQuery对象

结果:

image-20201009223200249

3. jQuery的核心函数

作为一般函数使用 $(param)

  1. 参数为函数:当dom加载完毕后执行此回调函数
  2. 参数为选择器字符串,查找所有匹配的标签,并将它们封装jQuery对象
  3. 参数为dom对象,将dom对象封装成jQuery对象
  4. 参数为html标签字符串(用的少),创建标签对象并封装成jQuery对象

作为对象使用 $.xxx()

  1. $.each() 隐式遍历数组
  2. $.trim() 去除两端的空格

案例练习

<div>
  <button id="btn">测试</button>
  <br/>
  <input type="text" name="msg1"/><br/>
  <input type="text" name="msg2"/><br/>
</div>
  1. 点击按钮显示按钮文本,显示一个新的输入框
  2. 遍历输出数组中的所有的元素
  3. 去掉“ my atguigu ”两端的空格

需求一:

$(function(){
      $(function () {
    //2). 参数为选择器(selector)字符串: 查找所有匹配的标签, 并将它们封装成jQuery对象
    var $btn = $("#btn")
    $btn.click(function () {
      //显示按钮的文本
      //this就是发生事件的dom元素对象(也就是button)
      //3). 参数为DOM对象: 将dom对象封装成jQuery对象
      var text = $(this).html()
      alert(text)
      //显示一个新的输入框
      //4). 参数为html标签字符串 (用得少): 创建标签对象并封装成jQuery对象
      $('<input type="text" name="msg3" /><br />').appendTo('div')
    })
  })
})

点击前:

image-20201009224744167

点击后:

image-20201009224808016

image-20201009224817731

需求二:

  var arr = [123, 'atguigu', true]
  // 1). $.each() : 隐式遍历数组
  $.each(arr, function (index, item) {
    console.log('第' + (index + 1) + '个元素的值为' + item)
  })

结果:

image-20201009225015631

需求三:

  var str = "  my atguigu  "
  // 2). $.trim() : 去除两端的空格
  console.log(str.trim() === 'my atguigu')//原生方法
  console.log($.trim(str) === 'my atguigu') //true

结果:

image-20201009225141401

4. jQuery对象

jQuery对象是一个包含所有匹配的任意多个dom的伪数组对象

基本行为

  1. size()/length 包含dom元素的个数,注意高版本size()被弃用了
  2. [index]/get(index): 得到对应位置的DOM元素
  3. each() 遍历包含所有的dom元素
  4. index() 得到所在兄弟元素中的下标

代码如下:

<button>测试一</button>
<button>测试二</button>
<button id="btn3">测试三</button>
<button>测试四</button>
  $(function () {
    var $btns = $('button')
    console.log($btns)
    // 需求1. 统计一共有多少个按钮
      /*size()/length: 包含的DOM元素个数*/
    console.log($btns.size(), $btns.length)

    // 需求2. 取出第2个button的文本
      /*[index]/get(index): 得到对应位置的DOM元素*/
    console.log($btns[1].innerHTML, $btns.get(1).innerHTML)

    // 需求3. 输出所有button标签的文本
      /*each(): 遍历包含的所有DOM元素*/
    $btns.each(function () {
      console.log(this.innerHTML)
    })

    // 需求4. 输出'测试三'按钮是所有按钮中的第几个
      /*index(): 得到在所在兄弟元素中的下标*/
    console.log($('#btn3').index())
  })

结果:

image-20201009225751296

5. jQuery中的基本选择器

  1. id选择器 #id
  2. 元素选择器 element
  3. 属性选择器 class
  4. 通配选择器 *
  5. 组合选择器 select1,select2,...,selectN
  6. 相交选择器(元素加属性选择器的组合) select1select2selectN

练习:

<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>
<br>
<ul>
  <li>AAAAA</li>
  <li title="hello">BBBBB(title="hello")</li>
  <li class="box">CCCCC(class="box")</li>
  <li title="hello">DDDDDD(title="hello")</li>
</ul>
 $(function () {
// 1. 选择id为div1的元素
     $('#div1').css('background', 'red')
// 2. 选择所有的div元素
     $('div').css('background', 'red')
// 3. 选择所有class属性为box的元素
     $('.box').css('background', 'red')
// 4. 选择所有的div和span元素
     $('div,span').css('background', 'red')
// 5. 选择所有class属性为box的div元素
     $('div.box').css('background', 'red')  //不能写.boxdiv
  })

6. jQuery层次选择器

层次选择器:查找子元素,后代,兄弟元素的选择器

  1. ancestor(具体的祖先元素选择器) descendant(具体的后代元素选择器)在给定的祖先元素下匹配所有的后代元素
  2. parent>child 在给定的父元素下匹配所有的子元素
  3. prev+next 匹配所有紧跟在 prev后面的next(第一个)元素
  4. prev~sibling 匹配 prev 元素之后的所有 siblings 元素

练习:

  <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>
 $(function () {
      //1. 选中ul下所有的的span
      $('ul span').css('background', 'red')
      //2. 选中ul下所有的子元素span
      $('ul>span').css('background', 'red')
      //3. 选中class为box的下一个li
      $('.box+li').css('background', 'red')
      //4. 选中ul下的class为box的元素后面的所有兄弟元素
      $('ul .box~*').css('background', 'red')
    })

7. jQuery过滤选择器

在原有的选择器匹配中进一步尽心过滤的选择器

<div id="div1" class="box">class为box的div1</div>
<div id="div2" class="box">class为box的div2</div>
<div id="div3">div3</div>
<span class="box">class为box的span</span>
<br/>
<ul>
  <li>AAAAA</li>
  <li title="hello">BBBBB</li>
  <li class="box">CCCCC</li>
  <li title="hello">DDDDDD</li>
  <li title="two">BBBBB</li>
  <li style="display:none">我本来是隐藏的</li>
</ul>
  $(function () {
//1. 选择第一个div
    $('div:first').css('background', 'red')
//2. 选择最后一个class为box的元素
    $('.box:last').css('background', 'red')
//3. 选择所有class属性不为box的div
    $('div:not(.box)').css('background', 'red')
//4. 选择第二个和第三个li元素
    $('li:gt(0):lt(2)').css('background', 'red') //注意这里的大于小于是依次执行不是同时执行索引起始位置发生变化,重新开始计算
    $('li:lt(3):gt(0)').css('background', 'red') //正确索引位置
//5. 选择内容为BBBBB的li
    $('li:contains(BBBBB)').css('background', 'red')
//6. 选择隐藏的li
  $('li:hidden ').show()
//7. 选择有title属性的li元素
    $('li[title]').css('background', 'red')
//8. 选择所有属性title为hello的li元素
    $('li[title=hello]').css('background', 'red')
  })

注意gt和lt的选择方式,两者选择都是开区间,下图介绍如何选择:

image-20201011185446091

8. jQuery 表单选择器

  1. 表单
  2. 表单对象属性
<form>
  用户名: <input type="text"/><br>
  密 码: <input type="password"/><br>
  爱 好:
  <input type="checkbox" checked="checked"/>篮球
  <input type="checkbox" checked="checked"/>足球
  <input type="checkbox" checked="checked"/>羽毛球 <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">北京</option>
    <option value="2" selected="selected">天津</option>
    <option value="3">河北</option>
  </select><br>
  <input type="submit" value="提交"/>
</form>
  $(function () {
//1. 选择不可用的文本输入框
    $(':input:disabled').css('background', 'red')
//2. 显示选择爱好的个数
    console.log($(':checkbox:checked').length)
//3. 显示选择的城市名称
    console.log($('select>option:selected').html())
    console.log($('select').val())  //得到的是选择的option的value
  })

9. $工具方法

  1. $.each(): 遍历数组或对象中的数据
  2. $.trim(): 去除字符串两边的空格
  3. $.type(obj): 得到数据的类型
  4. $.isArray(obj): 判断是否是数组
  5. $.isFunction(obj): 判断是否是函数
  6. $.parseJSON(json) : 解析json字符串转换为js对象/数组

10. 属性

操纵任意属性

  1. attr() 操纵属性值为非布尔值的属性
  2. prop() 操纵属性值为布尔值
  3. removeAttr() 删除属性

操作class属性

  1. addClass() 增加class类名
  2. removeClass() 移除对应类名,而不是整个属性都去除

操作html代码/文本/值

  1. html() 独写合一,既可以输出对应元素也可新增
  2. val() 与原生的innerHTML类似

练习:

<div id="div1" class="box" title="one">class为box的div1</div>
<div id="div2" class="box" title="two">class为box的div2</div>
<div id="div3">div3</div>
<span class="box">class为box的span</span>
<br/>
<ul>
  <li>AAAAA</li>
  <li title="hello" class="box2">BBBBB</li>
  <li class="box">CCCCC</li>
  <li title="hello">DDDDDD</li>
  <li title="two"><span>BBBBB</span></li>
</ul>

<input type="text" name="username" value="guiguClass"/>
<br>
<input type="checkbox">
<input type="checkbox">
<br>
<button>选中</button>
<button>不选中</button>
  $(function () {
//  1. 读取第一个div的title属性
     console.log($('div:first').attr('title'))
//  2. 给所有的div设置name属性(value为atguigu)
     $('div').attr('name', 'atguigu')
//  3. 移除所有div的title属性
     $('div').removeAttr('title')
//  4. 给所有的div设置class='guiguClass'
     $('div').attr('class', 'guiguClass')
//  5. 给所有的div添加class值(abc)
     $('div').addClass('abc')
//  6. 移除所有div的guiguClass的class
     $('div').removeClass('guiguClass')
//  7. 得到最后一个li的标签体文本
     console.log($('li:last').html())
//  8. 设置第一个li的标签体为"<h1>mmmmmmmmm</h1>"
     $('li:first').html('<h1>mmmmmmmmm</h1>')
//  9. 得到输入框中的value值
     console.log($(':text').val())
//  10. 将输入框的值设置为atguigu
     $(':text').val('atguigu')
//  11. 点击'全选'按钮实现全选
     $('button:first').click(function () {
      $(':checkbox').prop('checked', true)
    })
//  12. 点击'全不选'按钮实现全不选
    $('button:last').click(function () {
      $(':checkbox').prop('checked', false)
    }) 
  })

11.css操作

jQuery中操作/读取css

用法:css()

练习:

<p style="color: blue;">尚硅谷的后裔</p>
<p style="color: green;">太阳的后裔</p>

得到第一个标签的颜色:

console.log($('p:first').css('color'))

设置所有p标签的文本颜色为red

$('p').css('color','red');

设置第2个p的字体颜色(#ff0011),背景(blue),宽(300px), 高(30px)

/*对象方式添加css*/
$('p:eq(1)').css({
    color:'#ff0011',
    background:'blue',
    width:'300',
    height:'30'
})

offset和position

获取/设置标签的位置数据

  • offset() 相对于页面左上角的坐标
  • position() 相对于父元素左上角的坐标

练习:

<style type="text/css">
  * {
    margin: 0px;
  }
  .div1 {
    position: absolute;
    width: 200px;
    height: 200px;
    top: 20px;
    left: 10px;
    background: blue;
  }
  .div2 {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 50px;
    background: red;
    transition: all .2s;
  }
  .div3 {
    position: absolute;
    top: 250px;
  }
</style>
<body>
 <div class="div1">
   <div class="div2">测试offset</div>
 </div>
 <div class='div3'>
   <button id="btn1">读取offset和position</button>
   <button id="btn2">设置offset</button>
 </div>
</body>    

页面展示:

image-20201012222324780

  1. 点击btn2
/*
    打印 div1 相对于页面左上角的位置
    打印 div2 相对于页面左上角的位置
    打印 div1 相对于父元素左上角的位置
    打印 div2 相对于父元素左上角的位置
*/
    $('#btn1').click(function () {
      var offset1 = $('.div1').offset()
      console.log(offset1.left, offset1.top)
      var offset2 = $('.div2').offset()
      console.log(offset2.left, offset2.top)

      var position1 = $('.div1').position()
      console.log(position1.left, position1.top)
      var position2 = $('.div2').position()
      console.log(position2.left, position2.top)
    })

结果:

image-20201012222428653

  1. 点击 btn2,设置 div2 相对于页面的左上角的位置
  $('#btn2').click(function () {
      $('.div2').offset({
        left: 20,
        top: 40
      })
    })
/*点击btn1后再次输出位置信息*/

结果:

image-20201012222514669

元素的滚动

scrollTop()

读取/设置滚动条的y坐标

$(document.body).scrollTop()+$(document.documentElement).scrollTop()

读取页面滚动条的Y坐标(兼容chrome和IE),因为有些属性在特定的浏览器中属性值为0

$('body,html').scrollTop(60)

滚动到指定位置(兼容chrome和IE)

<div 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>
  /*
   需求:
   1. 得到div或页面滚动条的坐标
   2. 让div或页面的滚动条滚动到指定位置
   */
  $(function () {
    // 1. 得到div或页面滚动条的坐标
    $('#btn1').click(function () {
      console.log($('div').scrollTop())
      console.log($('body').scrollTop() + $('html').scrollTop())
      console.log($(document.body).scrollTop() + $(document.documentElement).scrollTop())
    })

    // 2. 让div或页面的滚动条滚动到指定位置
    $('#btn2').click(function () {
      $('div').scrollTop(150)
      //$('body, html').scrollTop(200)//这里是兼容写法。如果body不行,就带入html.
    })
  })

点击前:

image-20201012225659858

点击后:

image-20201012225733269

元素的尺寸

内容尺寸

height() height

width() width

内容尺寸

innerHeight() height+padding

innerWidth() width+padding

外部尺寸

outerHeight(false/true): height+padding+border 如果是true, 加上margin

outerWidth(false/true): width+padding+border 如果是true, 加上margin

练习:

<style>
  div {
    width: 100px;
    height: 150px;
    background: red;
    padding: 10px;
    border: 10px #fbd850 solid;
    margin: 10px;
  }
</style>
</head>

<body>
<div>div</div>
</body>    
  $(function () {
    var $div = $('div')
    // 内容尺寸
    console.log($div.width(), $div.height())
    // 内部尺寸
    console.log($div.innerWidth(), $div.innerHeight())
    //外部尺寸
    console.log($div.outerWidth(), $div.outerHeight())
    console.log($div.outerWidth(true), $div.outerHeight(true))
  })

结果:

image-20201012230741041

12. 筛选

过滤

在jQuery对象中的元素对象数组中过滤出一部分元素来

  1. first() 选中第一个元素
  2. last() 选中最后一个元素
  3. eq(index|-index) 按索引来选中元素
  4. filter(selector) 过滤出满足条件的元素
  5. not(selector) 过滤出不满足条件的元素
  6. has(selector) 选出满足条件的元素

练习:

<ul>
  <li>AAAAA</li>
  <li title="hello" class="box2">BBBBB</li>
  <li class="box">CCCCC</li>
  <li title="hello">DDDDDD</li>
  <li title="two"><span>BBBBB</span></li>
</ul>
<li>eeeee</li>
<li>EEEEE</li>
  $(function () {
    var $lis = $('ul>li');
//1. ul下li标签第一个
    $lis.first().css('background', 'red')
    $lis[0].style.background = 'red';//要区别开你操纵的时dom对象还是jquery对象
//2. ul下li标签的最后一个
     $lis.last().css('background', 'blue')
//3. ul下li标签的第二个
     $lis.eq(1).css('background', 'pink')
//4. ul下li标签中title属性为hello的
     //$lis.filter('[title=hello]').css('background', 'red')
//5. ul下li标签中title属性不为hello的
     $lis.not('[title=hello]').css('background', 'yellow')
     $lis.filter('[title][title!=hello]').css('background', 'green')//有title属性但是不为hello
//6. ul下li标签中有span子标签的
    // $lis.has('span').css('background', 'red')
  })

查找

在已经匹配出的元素集合中根据选择器查找孩子/父母/兄弟标签

  1. children(): 子标签中找
  2. find() : 后代标签中找
  3. parent() : 父标签
  4. prevAll() : 前面所有的兄弟标签
  5. nextAll() : 后面所有的兄弟标签
  6. siblings() : 前后所有的兄弟标签

练习:

<div id="div1" class="box" title="one">class为box的div1</div>
<div id="div2" class="box">class为box的div2</div>
<div id="div3">div3</div>
<span class="box">class为box的span</span>
<br/>
<div>
  <ul>
    <span>span文本1</span>
    <li>AAAAA</li>
    <li title="hello" class="box2">BBBBB</li>
    <li class="box" id='cc'>CCCCC</li>
    <li title="hello">DDDDDD</li>
    <li title="two"><span>span文本2</span></li>
    <span>span文本3</span>
  </ul>
  <span>span文本444</span><br>
  <li>eeeee</li>
  <li>EEEEE</li>
  <br>
</div>
  $(function () {
    var $ul = $('ul')
// 1. ul标签的第2个span子标签
     $ul.children('span:eq(1)').css('background', 'red')
// 2. ul标签的第2个span后代标签
     $ul.find('span:eq(1)').css('background', 'red')
// 3. ul标签的父标签
     $ul.parent().css('background', 'red')
// 4. id为cc的li标签的前面的所有li标签
     $ul.children('#cc').prevAll('li').css('background', 'red')
// 5. id为cc的li标签的所有兄弟li标签
     $ul.children('#cc').siblings('li').css('background', 'red')
  })

13. 文档的增删改查

添加替换元素

  • append(content) 向当前匹配的所有元素内部的最后插入指定内容
  • prepend(content) 向当前匹配的所有元素内部的最前面插入指定内容
  • before(content) 将指定内容插入到当前所有匹配元素的前面
  • before(content) 将指定内容插入到当前所有匹配元素的前面
  • after(content) 将指定内容插入到当前所有匹配元素的后面替换节点
  • replaceWith(content) 用指定内容替换所有匹配的标签删除节点

删除元素

  • empty() 删除所有匹配元素的子元素
  • remove() 删除所有匹配的元素

练习:

<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>
<br>
<ul id="ul2">
  <li>aaa</li>
  <li title="hello">bbb</li>
  <li class="box">ccc</li>
  <li title="hello">ddd</li>
  <li title="two">eee</li>
</ul>
  $(function () {
//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>replaceWith()替换的p</p>')
//6. 移除id为ul2的ul下的所有li
    //$('#ul2').empty();
    $('#ul2>li').remove()//注意empty和remove的区别一个是掏空内部一个是去除

  });

14. 事件的绑定与解绑

事件的绑定

事件的绑定由两种方式:

  1. eventName(function(){})

绑定对应事件名的监听, 例如:$('#div').click(function(){});

  1. on(eventName, funcion(){})

通用的绑定事件监听, 例如:$('#div').on('click', function(){})

优缺点:

eventName: 编码方便, 但只能加一个监听, 且有的事件监听不支持

on: 编码不方便, 可以添加多个监听, 且更通用

事件解绑

off(eventName)

事件的坐标

获取事件发生的位置

  • event.clientX, event.clientY 相对于视口的左上角
  • event.pageX, event.pageY 相对于页面的左上角
  • event.offsetX, event.offsetY 相对于事件元素左上角

事件的相关处理

  • 停止事件冒泡 : event.stopPropagation()
  • 阻止事件默认行为 : event.preventDefault()

练习:

  $(function () {
    // 1.给class为out的div的点击事件绑定监听函数,打印'out clicked'(用两种方法绑定)
    /*$('.out').click(function () {
      console.log('out click1')
    })*/
    $('.out').on('click', function () {
      console.log('out clicked2')
    })

    //2.给class为inner的div的鼠标移入和鼠标移出事件绑定监听函数(用3种方法绑定)
    /*$('.inner')
      .mouseenter(function () {
        console.log('进入...')
      })
      .mouseleave(function () {
        console.log('离开...')
      })*/
    $('.inner')
      .on('mouseenter', function () {
        console.log('进入...')
      })
      .on('mouseleave', function () {
        console.log('离开...')
      })
    /*$('.inner').hover(function () {
      console.log('进入...')
    }, function () {
      console.log('离开...')
    })*/

    //3. 点击btn1解除inner上的所有事件监听
    $('#btn1').click(function () {
      $('.inner').off()
    })

    //4.点击btn2解除inner上的mouseenter事件
    $('#btn2').click(function () {
      $('.inner').off('mouseenter')
    })

    //5. 点击btn3得到事件坐标
    $('#btn3').click(function (event) {
      console.log(event.offsetX, event.offsetY)
      console.log(event.clientX, event.clientY)
      console.log(event.pageX, event.pageY)
    })

    //6. 点击.inner区域, 外部点击监听不响应
    $('.inner').click(function (event) {
      console.log('click inner')
      // 停止事件冒泡
      event.stopPropagation()
    })

    //7. 点击链接, 如果当前时间是偶数不跳转
    $('#test4').click(function (event) {
      var time = Date.now();
      alert(time)
      if(time%2===0) {
        // 阻止事件默认行为
        event.preventDefault()
      }
    })
  })

区别mouseover与mouseenter?

mouseover: 在移入子元素时也会触发, 对应mouseout

mouseenter: 只在移入当前元素时才触发, 对应mouseleave

hover()使用的就是mouseenter()和mouseleave()

15. 事件委托

将多个子元素(li)的事件监听委托给父辈元素(ul)处理,监听回调是加在了父辈元素上, 当操作任何一个子元素(li)时, 事件会冒泡到父辈元素(ul),父辈元素不会直接处理事件, 而是根据event.target得到发生事件的子元素(li), 通过这个子元素调用事件回调函数

好处:添加新的子元素, 自动有事件响应处理,减少事件监听的数量: n==>1

jQuery的事件委托API:

  • 设置事件委托: $(parentSelector).delegate(childrenSelector, eventName, callback)
  • 移除事件委托: $(parentSelector).undelegate(eventName)
<ul>
  <li>1111</li>
  <li>2222</li>
  <li>3333</li>
  <li>4444</li>
</ul>

<li>22222</li>
<br>
<button id="btn1">添加新的li</button>
<button id="btn2">删除ul上的事件委托的监听器</button>
  $(function () {
    //事件委托
    $('ul').delegate('li', 'click', function () {
      this.style.background = 'red'
    })

    $('#btn1').click(function () {
      $('ul').append('<li>xxxxxxxxx</li>')
    })

    $('#btn2').click(function () {
      // 移除事件委托
      $('ul').undelegate()
    })
  })

16. 动画

淡入淡出

不断改变元素的透明度 (opacity)来实现的

  1. fadeIn(): 带动画的显示
  2. fadeOut(): 带动画隐藏
  3. fadeToggle(): 带动画切换显示/隐藏
  $(function () {
    //1. 点击 btn1 实现 慢慢淡出
    $('#btn1').click(function () {
      // $('.div1').fadeOut()
      // $('.div1').fadeOut(1000)可以指定数值单位毫秒
      $('.div1').fadeOut('fast')
      /*
      slow: 600
      normal: 200
      fast: 200
       */
    })

    //2. 点击 btn3 实现 慢慢淡入
    $('#btn2').click(function () {
      $('.div1').fadeIn()
    })

    //3. 点击 btn3 实现 淡出/淡入切换 动画完成会执行回调函数
    $('#btn3').click(function () {
      $('.div1').fadeToggle(function () {
        alert('动画结束了')
      })
    })
  })

滑动

滑动动画,不断改变元素的高度来显示的

  1. slideDown(): 带动画的展开
  2. slideUp(): 带动画的收缩
  3. slideToggle(): 带动画的切换展开/收缩
  $(function () {
    //1. 点击 btn1 实现 向上滑动
    $('#btn1').click(function () {
      $('div').slideUp()
    })

    //2. 点击 btn3 实现 向下滑动
    $('#btn2').click(function () {
      $('div').slideDown()
    })

    //3. 点击 btn3 实现 向上/向下切换
    $('#btn3').click(function () {
      $('div').slideToggle(300,function(){
        console.log('完成!!')
      })
    })
  })

显示与隐藏

显示隐藏,默认没有动画 从左上角开始动画 改变宽高和透明度

  1. show(): (不)带动画的显示
  2. hide(): (不)带动画的隐藏
  3. toggle(): (不)带动画的切换显示/隐藏
  $(function () {
    //1. 点击btn1, 立即显示
    $('#btn1').click(function () {
      $('div').show()
    })

    //2. 点击btn2, 慢慢显示
    $('#btn2').click(function () {
      $('div').show(1000)
    })

    //3. 点击btn3, 慢慢隐藏
    $('#btn3').click(function () {
      $('div').hide(2000)
    })

    //4. 点击btn4, 切换显示/隐藏
    $('#btn4').click(function () {
      $('div').toggle(1000)
    })
  })

自定义动画

jQuery动画本质 : 在指定时间内不断改变元素样式值来实现的

  1. animate(): 自定义动画效果的动画
  2. stop(): 停止动画

练习:

  <style type="text/css">
    * {
      margin: 0px;
    }

    .div1 {
      position: absolute;
      width: 100px;
      height: 100px;
      top: 50px;
      left: 300px;
      background: red;
    }
  </style>
</head>
<body>
<button id="btn1">逐渐扩大</button>
<button id="btn2">移动到指定位置</button>
<button id="btn3">移动指定距离</button>
<button id="btn4">停止动画</button>

<div class="div1">
  爱在西元前,学在尚硅谷
</div>
</body>
  /*
   需求:
   1. 逐渐扩大
     1). 宽/高都扩为200px
     2). 宽先扩为200px, 高后扩为200px
   2. 移动到指定位置
     1).移动到(500, 100)处
     2).移动到(100, 20)处
   3.移动指定的距离
     1). 移动距离为(100, 50)
     2). 移动距离为(-100, -20)
   4. 停止动画
   */
  let $div1 = $('.div1');
  $('#btn1').click(function(){
    $div1.animate({
      width:200,
    },1000).animate({
      height:200,
    },2000);

  });
  $('#btn2').click(function(){
    $div1.animate({//向右下移动
      left:500,
      top:100
    },1000).animate({
      left:100,
      top:20
    },1000);
  });
  
  $('#btn3').click(function(){
    $div1.animate({//向右下移动
      left:'+=100',
      top:'+=50'
    },1000)    
  });
  $('#btn4').click(function(){
    $div1.stop();//注意有几个动画就要停止几次停止顺序按执行顺序来
  });

17.扩展插件

  1. 扩展jQuery的工具方法 $.extend(object)
  2. 扩展jQuery对象的方法 $.fn.extend(object)

自定义插件:

/*
 扩展jQuery的工具方法 : $.extend(object)
   min(a, b) : 返回较小的值
   max(c, d) : 返回较大的值
   leftTrim() : 去掉字符串左边的空格
   rightTrim() : 去掉字符串右边的空格
 */

//正则
/*
 ^   匹配字符串开始
 \s  匹配空格
 +   匹配一次或者多次
 $   匹配字符串的末尾
 */
//扩展$ 
$.extend({
  min: function (a, b) {
    return (a < b) ? a : b
  },
  max: function (a, b) {
    return (a > b) ? a : b
  },
  leftTrim: function (strToBeTrimed) {
    return strToBeTrimed.replace(/^\s+/, '')
  },
  rightTrim: function (strToBeTrimed) {
    return strToBeTrimed.replace(/\s+$/, '')
  }
})


//扩展 $('#id').XXXXX
//$.fn.extend(object)
// checkAll() : 全选
// unCheckAll() : 全不选
// reverseCheck() : 全反选
$.fn.extend({
  checkAll: function () {
    // console.log('checkAll')
    this.prop('checked', true)//this为jQuery对象
  },
  unCheckAll: function () {
    this.prop('checked', false)
  },
  reverseCheck: function () {
    this.each(function () {
      this.checked = !this.checked//this为dom元素
    })
  }
})
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>25_扩展插件</title>
  <style type="text/css">
    * {
      margin: 0px;
    }

    .div1 {
      position: absolute;
      width: 100px;
      height: 100px;
      top: 50px;
      left: 10px;
      background: red;
    }
  </style>
</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="checkedAllBtn" value="全 选"/>
<input type="button" id="checkedNoBtn" value="全不选"/>
<input type="button" id="reverseCheckedBtn" value="反选"/>
    
<script src="js/jquery-1.10.1.js" type="text/javascript"></script>
<script src="js/my_jQuery_plugin.js" type="text/javascript"></script>
<script type="text/javascript">
  // 得到最大最小值
  var a = 1
  var b = 2
  var result_min = $.min(a, b)
  var result_max = $.max(a, b)
  console.log(result_min)
  console.log(result_max)

  // 左trim 右trim
  var str = '   悟空    '
  console.log('|' + str + '|')
  var resultStrLeft = $.leftTrim(str)
  console.log('|' + resultStrLeft + '|')
  var resultStrRight = $.rightTrim(str)
  console.log('|' + resultStrRight + '|');

  //全选
  $('#checkedAllBtn').click(function () {
    $(':checkbox').checkAll()
  })

  //全不选
  $('#checkedNoBtn').click(function () {
    $(':checkbox').unCheckAll()
  })

  //反选
  $('#reverseCheckedBtn').click(function () {
    $(':checkbox').reverseCheck()
  })
</script>
</body>
</html>

18. 多库共存

问题 : 如果有2个库都有$, 就存在冲突

解决 : jQuery库可以释放$的使用权, 让另一个库可以正常使用, 此时jQuery库只能使用jQuery了

API : jQuery.noConflict()

19. onload和ready的区别

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

  • window.onload
  1. 包括页面的图片加载完后才会回调(晚)
  2. 只能有一个监听回调
  • $(document).ready() 等同于: $(function(){})
  1. 页面加载完,不一定图片加载完毕就回调(早)
  2. 可以有多个监听回调
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>window.onload与$(document).ready()</title>
</head>
<body>
<h1>测试window.onload与$(document).ready()</h1>
<img id="logo" src="https://gss0.bdstatic.com/5bVWsj_p_tVS5dKfpU_Y_D3/res/r/image/2017-05-19/6fec71d56242b74eb24b4ac80b817eac.png">

<!--
区别: window.onload与 $(document).ready()
  * window.onload
    * 包括页面的图片加载完后才会回调(晚)
    * 只能有一个监听回调
  * $(document).ready()
    * 等同于: $(function(){})
    * 页面加载完,不一定图片加载完毕就回调(早)
    * 可以有多个监听回调
-->
<script type="text/javascript" src="js/jquery-1.10.1.js"></script>
<script type="text/javascript">
  /*
   需求:
   1. 直接打印img的宽度,观察其值
   2. 在 $(function(){}) 中 打印 img 的宽度
   3. 在 window.onload 中打印宽度
   4. 在 img 加载完成后打印宽度
   */
  var $logo = $('#logo')
  console.log('直接',$logo.width()) // 获取不到的
  $(function () {
    console.log('$1()', $logo.width())
  })
  $(function () {
    console.log('$2()', $logo.width())
  })

  window.onload = function () {
    console.log('onload1()')
  }
  window.onload = function () {
    console.log('onload2()', $logo.width())
  }

  $logo.on('load', function () {
    console.log('load', this.width)
  })
</script>
</body>
</html>

结果:

image-20201013171901729

注意再次刷新$()也会获取到的,这个是缓存问题,比较的时候注意避免

Last modification:October 16, 2020
如果觉得我的文章对你有用,请随意赞赏