目录
- 1_ jQuery事件处理
 - 1.1_认识事件(Event)
 - 1.2_click和on的区别
 - 1.3_ jQuery的事件冒泡
 - 1.4_jQuery的事件对象( Event Object)
 - 1.5_ jQuery的事件委托(event delegation)
 - 1.6_ jQuery常见的事件
 - 1.7_小案例
 
- 2_ jQuery 动画
 - 2.1_介绍
 - 2.2_jQuery常见动画函数
 - 2.3_ jQuery元素中的动画队列
 - 2.4_小案例
 
1_ jQuery事件处理
1.1_认识事件(Event)
Web页面经常需要和用户之间进行交互,而交互的过程中可能想要捕捉这个交互的过程:
- 比如用户点击了某个按钮、用户在输入框里面输入了某个文本、用户鼠标经过了某个位置;
 - 浏览器需要搭建一条JavaScript代码和事件之间的桥梁;
 - 当某个事件发生时,让JavaScript执行某个函数,所以需要针对事件编写处理程序(handler);
 
原生事件监听方法:
- 事件监听方式一:在script中直接监听(很少使用)。
 - 事件监听方式二:DOM属性,通过元素的
on来监听事件。 - 事件监听方式三:通过EventTarget中的
addEventListener来监听。 
jQuery事件监听方法:
- 事件监听方式一:直接调用jQuery对象中的事件处理函数来监听,例如:click,mouseenter…。
 - 事件监听方式二:调用jQuery对象中的
on函数来监听,使用off函数来取消监听。 
  <ul id="list" class="panel">
    <li class="li-1">li-1</li>
    <li class="li-2">li-2</li>
    <li class="li-3">li-3</li>
    <li class="li-4">li-4</li>
    <li class="li-5">li-5</li>
  </ul>
  <button class="cancel">取消事件的监听</button>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() { 
      // 监听事件
      // 1.使用on来监听事件
      $('ul').on('click', function() {
        console.log('click1')
      })
      // 2.使用click来监听事件
      $('ul').click(function() {
        console.log('click2')
      })
      // 3.使用mouseenter来监听事件
      $('ul').mouseenter(function() {
        console.log('mouseenter')
      })
      // 取消监听事件off
      $('.cancel').click(function() {
        // $('ul').off() // 取消ul元素上所有的事件
        // $('ul').off('mouseenter')
        $('ul').off('click')
      })
      // 使用程序-自动触发事件
      $('ul').trigger('click')  // 模拟用户点击了ul元素
      $('ul').trigger('mouseenter')
    })
  </script>
 
1.2_click和on的区别
click是on的简写。它们重复监听,不会出现覆盖情况,都支持事件委托,底层用的是addEventListener。
 如果 on 没有使用 selector 的话,那么和使用click是一样的。
on 函数可以接受一个 selector 参数,用于筛选 可触发事件 的后代元素。
 on 函数支持给事件添加命名空间。
  <ul id="list" class="panel">
    <li class="li-1">li-1</li>
    <li class="li-2">li-2</li>
    <li class="li-3">li-3</li>
    <li class="li-4">li-4</li>
    <li class="li-5">li-5</li>
  </ul>
  <button class="cancel">取消事件的监听</button>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() {
     
      // 监听事件
      // 1.使用on来监听事件 ( 支持给事件添加命名空间: xixi ;并且支持一个selector选择器: .li-4 )
      $('ul').on('click.xixi','.li-4', function() {
        console.log('click1')
      })
      // 2.使用click来监听事件
      $('ul').click(function() {
        console.log('click2')
      })
      // 取消监听事件
      $('.cancel').click(function() {
        $('ul').off('click.xixi')
      })
    })
  </script>
 
补充:click和on的this都是指向原生的DOM Element
    $(function() {
      $('ul').click(function() {
        console.log("%O", this) // DOM Element -> UL
      }) 
      $('ul').on('click', function() {
        console.log(this) // DOM Element -> UL
      })
      $('ul li').click(function() {
        console.log(this) // DOM Element -> UL
      })
      // 底层实现的原理
      var lisEl = $('ul li').get() // [li, li, li]
      for(var liEL of lisEl ){
        liEL.addEventListener('click', function() {
          console.log(this)
        })
      }
      $('ul li').click(function() {
        console.log( $(this) ) // DOM Element 转成 jQuery 对象,故this指向JQ对象
      })
      
      $('ul li').click(() => {
        console.log(this) //立即执行函数的this不绑定自身的原生对象,往上层作用域找,是document对象
      })
    })
 
1.3_ jQuery的事件冒泡
默认情况下事件是从最内层(如:span -> body)向外依次传递的顺序,这个顺序称之为事件冒泡(Event Bubble);
另外一种监听事件流的方式就是从外层到内层(如:body -> span),这种称之为事件捕获(Event Capture);
为什么会产生两种不同的处理流呢?
- 这是因为早期在浏览器开发时,不管是IE还是Netscape公司都发现了这个问题;
 - 但是他们采用了完全相反的事件流来对事件进行了传递;
 - IE<9仅采用了事件冒泡的方式,Netscape采用了事件捕获的方式;
 - IE9+和现在所有主流浏览器都已支持这两种方式。
 
jQuery为了更好的兼容IE浏览器,底层并没有实现事件捕获。
1.4_jQuery的事件对象( Event Object)
jQuery事件系统的规范是根据W3C的标准来制定jQuery事件对象。
原始事件对象的大多数属性都被复制到新的jQuery事件对象上。如,以下原生的事件属性被复制到jQuery事件对象中:
 altKey, clientX, clientY, currentTarget, data, detail, key, keyCode, offsetX, offsetY, originalTarget, pageX, pageY, relatedTarget, screenX, screenY, target, …
jQuery事件对象通用的属性(以下属性已实现跨浏览器的兼容): target、relatedTarget、pageX、pageY、which、metaKey
  <div class="box">
    div
    <span class="content">span</span>
  </div>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    $(function() {
      // 1.获取原生的事件对象
      var divEl = document.querySelector('.box')
      divEl.addEventListener('click', function(event) {
        console.log(event)
      })
      // 2.获取jQuery的事件对象
      $('.box').click(function($event) {
        console.log($event) // 是jQuery的事件对象
        console.log($event.originalEvent) // 拿到原生的事件对象
      })
    })
  </script>
 
jQuery事件对象常用的方法:
- preventDefault() : 取消事件的默认行为(例如,a标签、表单事件等)。
 - stopPropagation() : 阻止事件的进一步传递(例如,事件冒泡)。
 
要访问其它事件的属性,可以使用 event.originalEvent 获取原生对象
  <div class="box">
    div
    <span class="content">span</span>
  </div>
  <a href="https://www.jd.com">京东商城</a>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() {
      $('a').click(function($event) {
        $event.preventDefault()  // 阻止a元素的默认行为
        console.log('点击a元素  但阻止a元素的默认行为')
      })
      $('.content').click(function($event) {
        $event.stopPropagation() // 阻止事件的冒泡
        console.log('点击span 但阻止事件的冒泡')
      })
      
      $('.box').on('click', function() {
        console.log('点击了粉色盒子')
      })
      $('body').on('click', function() {
        console.log('点击了body')
      })
    })
 
1.5_ jQuery的事件委托(event delegation)
事件冒泡在某种情况下可以帮助实现强大的事件处理模式 – 事件委托模式(也是一种设计模式)
JQuery事件委托模式?
- 当子元素被点击时,父元素可以通过冒泡监听到子元素的点击;
 - 并且可以通过
event.target获取到当前监听事件的元素(event.currentTarget获取到的是处理事件的元素); 
案例:一个ul中存放多个li,使用事件委托的模式来监听li中子元素的点击事件。
  <ul id="list" class="panel">
    <li class="li-1">li-1
      <p class="p1">我是p元素</p>
    </li>
    <li class="li-2">li-2
      <p  class="p2">我是p元素</p>
    </li>
    <li class="li-3">li-3
      <p  class="p3">我是p元素</p>
    </li>
    <li class="li-4">li-4
      <p  class="p4">我是p元素</p>
    </li>
    <li class="li-5">li-5
      <p  class="p5">我是p元素</p>
    </li>
  </ul>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() {
      // 事件的委托
      $('ul').on('click', function(event) {
        console.log(event.target)  // 点击哪个,打印哪个元素及其后代元素。
      })
      // 仅仅监听li中元素的点击事件( 筛选出 可触发事件的 后代元素 )
      $('ul').on('click', 'li p' , function(event) {
        console.log(event.target)  // 只打印p元素,点击其他的元素没反应【<p class="p1">我是p元素</p>】
      })
    })
  </script>
 
1.6_ jQuery常见的事件
鼠标事件(Mouse Events)
- .click() 、.dblclick()、.hover()、.mousedown() 、.mouseup()
 - .mouseenter()、.mouseleave()、.mousemove()
 - .mouseover()、.mouseout() 、.contextmenu()、.toggle()
 
mouseenter()和mouseleave()
- 不支持冒泡
 - 进入子元素依然属于在该元素内,没有任何反应
 mouseover()和mouseout()
- 支持冒泡
 - 进入元素的子元素时
 
- 先调用父元素的mouseout
 - 再调用子元素的mouseover
 - 因为支持冒泡,所以会将mouseover传递到父元素中;
 
键盘事件(Keyboard Events): .keydown() 、.keypress()、.keyup()
文档事件(Document Loading Events): load、ready()、.unload
表单事件(Form Events): .blur() 、.focus()、.change()、.submit()、.select()
浏览器事件(Browser Events): .resize()、.scroll()
<input type="text">
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    $(function() {
      // on('hover', func)
      // 1.hover 底层使用的是: mouseenter or mouseleaver
      // hover()中的两个函数,前者是mouseenter(),后者是mouseleaver()
      $('ul').hover(function() {
        console.log('鼠标悬浮在ul')
      }, function() {
        console.log('鼠标离开在ul')
      })
      // 2.监听浏览器resize事件 ( 可以优化进行throttle 节流 ) 
      // 浏览器窗口大小被改动时,被监听到
      $(window).resize(function() {
        console.log('resize  changing')
      })
      // // 3.表单事件
      // 输入框聚焦
      $('input').focus(function() {
        console.log('input focus事件')
      })
      // 输入框失焦
      $('input').blur(function() {
        console.log('input blur事件')
      })
      // // input ( 注意可以进行debounce 防抖操作 )
      $('input').on('input', function() {
       console.log( $('input').val() )
       console.log( $(this).val() )
      })
    })
  </script>
 
1.7_小案例
实现选项卡的切换
  <style>
    .nav{
      background-color: #43240c;
      color: white;
    }
    .nav-bar{
      display: flex;
      width: 1200px;
      height: 46px;
      line-height: 46px;
      margin: 0 auto;
    }
    .item{
      width: 160px;
      text-align: center;
      cursor: pointer;
    }
    .item.active{
      background-color: #fee44e;
      color: #43200c;
    }
  </style>
</head>
<body>
  
  <div class="nav">
    <div class="nav-bar" >
      <div class="item active">首页</div>
      <div class="item">9块9包邮</div>
      <div class="item">超值大额券</div>
      <div class="item">降温急救穿搭</div>
    </div>
  </div>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() {
      //【解释】 监听 类名为.item的点击事件,若点击某个.item,则给其类名添加active,其余兄弟元素移除类名active
      $('.item').on('click', function() {
        $(this).addClass('active').siblings().removeClass('active')
      })
      console.log($('.item:eq(1)').siblings())
    })
  </script>
</body>
 
2_ jQuery 动画
2.1_介绍
.animate(): 执行一组 CSS属性的自定义动画,允许支持数字的CSS属性上创建动画。
-  
.animate( properties [, duration ] [, easing ] [, complete ] )
 -  
.animate( properties, options )
-  
propertys参数的支持:
-  
数值:number 、string
 -  
关键字:
show、hide和toggle -  
相对值:+= 、 -=
 -  
支持 em 、% 单位(可能会进行单位转换)。
 
 -  
 
 -  
 
自定义修改宽高度动画
- height :100% -> 0
 - width: 100% -> 0
 - opacity: 1 - >0
 
案例:利用.animate()函数完成动画的显示、隐藏、切换
  <style>
    body{
      height: 200px;
    }
    .box{
      width: 200px;
      height: 100px;
      background-color: pink;
    }
  </style>
<body>
 
  <button class="hide">隐藏</button>
  <button class="show">显示</button>
  <button class="toggle">切换</button>
  <div class="box">box</div>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    $(function() {
      //隐藏动画
      $('.hide').click(function() {
        $('.box').animate({
          opacity: 0,
          height:0,
          width: 0
        }, 'slow', function() {   // number | 关键之: slow->600 fast->200
          console.log('动画执行完成')
        })
      })
      //显示动画
      $('.show').click(function() {
        $('.box').animate({
          opacity: 1,
          height: 100,
          width: 200
        }, 'fast', function() {
          console.log('动画执行完成')
        })
      })
      //利用toggle关键字,切换动画
      $('.toggle').click(function() {
        // 关键词toggle有切换的作用
        $('.box').animate({
          opacity: 'toggle',
          height: 'toggle',
          width: 'toggle'
        }, 400, function() {
          console.log('动画执行完成')
        })
      })
    })
  </script>
 
2.2_jQuery常见动画函数
显示和隐藏匹配的元素
- .hide() 、.hide( [duration ] [, complete ] )、.hide( options ) - 隐藏元素
 - .show() 、.show( [duration ] [, complete ] )、.show( options ) - 显示元素
 - .toggle() 、.toggle( [duration ] [, complete ] )、.toggle( options ) -显示或者隐藏元素(来回切换)
 
利用动画函数,优化刚才的案例
 $(function() {
      $('.hide').click(function() {
        $('.box').hide('slow', function() {
          console.log('动画执行完成')
        })
      })
      $('.show').click(function() {
        $('.box').show('fast', function() {
          console.log('动画执行完成')
        })
      })
     
        $('.box').toggle({
          duration: 3000,
          complete: function() {
            console.log('动画执行完成')
          }
        })
      })
    })
 
淡入淡出
- .fadeIn()、.fadeIn( [duration ] [, complete ] )、.fadeIn( options ) - 淡入动画
 - .fadeOut()、.fadeOut( [duration ] [, complete ] )、.fadeOut( options ) -淡出动画
 - .fadeToggle()、.fadeToggle( [duration ] [, complete ] )、.fadeToggle( options ) - 淡入淡出的切换
 - .fadeTo( duration, opacity [, complete ] ) - 渐变到
 
2.3_ jQuery元素中的动画队列
jQuery匹配元素中的animate和delay动画是通过一个动画队列(queue)来维护的。例如执行下面的动画都会添加到动画队列中:
- .hide() 、 .show()
 - .fadeIn() 、.fadeOut()
 - .animate()、delay()
 
.queue():查看当前选中元素中的动画队列。
.stop( [clearQueue ] [, jumpToEnd ] ):停止匹配元素上当前正在运行的动画。
- clearQueue :一个布尔值,指示是否也删除排队中的动画。默认为false
 - jumpToEnd :一个布尔值,指示是否立即完成当前动画。默认为false
 
demo:
  <style>
    .box{
      position: relative;
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
<body>
  <button class="start">开始动画</button>  
  <button class="stop">停止动画</button>  
  <button class="queue">查看动画队列</button> 
  <div class="box">box</div>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 监听文档完全解析完成
    $(function() {
      var $box = $('.box')
      $('.start').click(function() {
        // 竖直向下走100px
        $box.animate({
          top: 100
        }, 2000)
        // 水平向右走100px
        $box.animate({
          left: 100
        }, 2000)
        // 竖直向上走100px
        $box.animate({
          top: 0
        },2000)
        // 水平向左走100px
        $box.animate({
          left: 0
        }, 2000)
      })
      $('.queue').click(function() {
        console.log( $box.queue() )  // 查看动画队列 。一旦动画队列启动运行,执行这个函数只能查看剩余的动画
      })
      $('.stop').click(function() {
        // $box.stop()  // 停止 fx 动画队列( 停止当前执行的动画,还会继续执行动画队列中其它的动画 )
        // stop(false, false) //默认值。不停止
        // $box.stop(true) // 停止所有的动画(包括当前的动画), 清空了动画队列,
         $box.stop(true, true) // 清空了动画队列, 立即执行完当前的动画
      })
    })
  </script>
 
2.4_小案例
点击关闭按钮,做关闭侧边栏动画.、。
监听关闭按钮,检测到点击事件,先进行关闭最下方图片的动画,然后图片大盒子的宽度逐步归零,最后图片消失

  <style>
    .box{
      position: fixed;
      bottom: 0;
      right: 0;
    }
    img{
      vertical-align: bottom;
    }
    .close{
      position: absolute;
      top: 0;
      right: 0;
      width: 25px;
      height: 25px;
      cursor: pointer;
      /* border: 1px solid red; */
    }
  </style>
<body>
  
  <div class="box">
    <span class="close"></span>
    <div class="top">
      <img src="./images/top.png" alt="">
    </div>
    <div class="bottom">
      <img src="./images/bottom.png" alt="">
    </div>
  </div>
  <script src="../libs/jquery-3.6.0.js"></script>
  <script>
    // 1.监听文档完全解析完成
    $(function() {
      // 【解释】监听关闭按钮,检测到点击事件,先进行关闭最下方图片的动画,然后图片大盒子的宽度逐步归零,最后图片消失
      $('.close').click(function() {
        $('.bottom').animate({height: 0}, 600, function() {
          $('.box').animate({width: 0}, 600, function() {
            $('.box').css('display', 'none')
          })
        })
      })
    })
  </script>
</body>
 
 
 
 
 


















