JS.DAY15.笔记

113 阅读5分钟

一、事件

- 事件的基础知识

  1. 事件:事情发生了并得到处理
  2. 事件三要素:事件源.事件类型=事件处理函数document.onclick = function(){}
  3. 事件处理函数是异步的
  4. 这个匿名函数是在事件发生以后,由系统调用
  5. 一般事件处理函数没有特定的返回值,但是也可以使用return

- 事件处理函数的参数

  1. 事假处理函数的第一个参数表示的是事件对象
  2. 事件对象是用户记录事情发生的整个过程
        document.onclick = function(a,b){
            console.log(a);
            // 事件处理函数只有一个参数
            console.log(b);//undifined  
        }
  1. 参数e指的是事件对象,低版本浏览器只能使用event来记录事件对象
      // e 
        document.onclick = function(e){
            // 大多数浏览器支持事件处理函数的第一个参数做事件对象
            console.log(e);
       

            // 低版本浏览器只能使用event来记录事件对象
            console.log(event);

            e = e || event

            // target目标 --- 具体是由哪个标签触发的
            console.log(e.target);
            // this 指向事件源
            console.log(this);

            console.log(e.clientX);

        
        }
      

- 绑定事件的方式

  1. 行内js onclick="fn()"
<div class="a" onclick="fn(6)"> 12</div>

 function fn(n){
            console.log(n);
        }

  1. 事件绑定 oDiv.onclick = function(){}
        // 后面的事件覆盖前面
        oDiv.onclick = function(){
            console.log(11);
        }
  1. 事件监听 oDiv.addEventListener(事件类型,事件处理函数)。事件监听和普通事件绑定的区别,是事件监听不会被覆盖
// 事件监听,不会覆盖, (事件类型,事件处理函数)
        oDiv.addEventListener("click",function(){
            console.log(4);
        })
        oDiv.addEventListener("click",function(){
            console.log(5);
        })
  1. 兼容问题处理
        // 添加事件监听
        function addEvent(ele,type,cb){
            // 先判断window对象下是否存在这个方法
            if(window.addEventListener){
                ele.addEventListener(type,cb)
            }else{
                ele.addEventListener("on" + type ,cb)
            }

        }

- 事件移除

  1. 行内js和普通事件绑定都可以通过重新赋值,以覆盖的方式进行移除
<div class="a" onclick="fn()"></div>

var oDiv = document.querySelector(".a");
// 通过覆盖,移除。重新赋值(可以写任意值)一般建议写null
oDiv.onclick = null //onclick是一个对象,可以等于任意值
  1. 事件监听的方式,需要写成具名函数才能被移除(注意:移除的时候),需要一个一个的移除
        oDiv.addEventListener("click",fn)
        // 移除
        oDiv.removeEventListener("click",fn)
  1. 兼容问题处理
        // 移除事件监听
        function removeEvent(ele,type,cb){
            // 先判断window对象下是否存在这个方法
            if(window.removeEventListener){
                ele.removeEventListener(type,cb)
            }else{
                ele.detachEvent("on" + type ,cb)
            }

        }

- 事件流

  1. 什么是事件流:事件流描述的是从页面中接受事件的顺序
  2. 但有意思的是,微软(IE)和网景(Netscape)开发团队居然提出了两个截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)
  3. 实现事件捕获的方式: addEventListener(type , fn , true) 第三个参数表示是否支持事件捕获
  4. 事件捕获:事件捕获流的思想是不太具体的DOM节点应该更早接收到事件,而最具体的节点应该最后接收到事件(从里向外)
  5. 事件冒泡:IE提出的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(从外向内)
  6. IE提出的是冒泡流,而网景提出的是捕获流,后来在W3C组织的统一之下,JS支持了冒泡流和捕获流,但是目前低版本的IE浏览器还是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以为了能够兼容更多的浏览器,建议大家使用冒泡流。
  7. 事件流包含的三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
        var oDiv = document.querySelector('.a')
        var oP = document.querySelector('p') ;
        var oSpan = document.querySelector('span')


        // 默认是事件冒泡 --- 从里向外
        oDiv.addEventListener( 'click' , function () {  
            console.log('我是最外面的');
        })

        oP.addEventListener( 'click' , function () {  
            console.log('我是中间的');
        })

        oSpan.addEventListener( 'click' , function () {  
            console.log('我是最里面的');
        })

        var oDiv = document.querySelector('.a')
        var oP = document.querySelector('p') ;
        var oSpan = document.querySelector('span')


 

        // 事件捕获 --- 从外向内
        oDiv.addEventListener( 'click' , function () {  
            console.log('我是最外面的');
        } , true)

        oP.addEventListener( 'click' , function () {  
            console.log('我是中间的');
        } , true)

        oSpan.addEventListener( 'click' , function () {  
            console.log('我是最里面的');
        } , true)

- 阻止事件冒泡

  1. e 事件对象
  2. 利用事件对象阻止事件
  3. e.stopPropagation() 主流浏览器
  4. e.cancelBubble = true; IE
  5. 兼容问题处理
       oDiv = document.querySelector(".a")
        oP = document.querySelector("p")
        oSpan = document.querySelector("span")


        // 事件监听
        // 默认事件冒泡
        oDiv.addEventListener("click",function () {
            console.log("div");
        })
        oP.addEventListener("click",function (e) {
            e = e || event;
            // 主流浏览器写法
            // e.stopPropagation()
            // 低版本IE取消事件冒泡的方法
            // e.cancelBubble = true;
            // 兼容代码
            if(e.stopPropagation){
                e.stopPropagation()
            }else{
                e.cancelBubble = true;
            }
            console.log("p");
        })
        oSpan.addEventListener("click",function () {
            console.log("我是span");
        })

事件委托

  1. 什么是事件委托:子元素的同类型事件委托给父元素来实现

  2. 为什么使用事件委托:减少事件处理函数、可以给将来对象绑定事件

  3. 事件委托的原理:事件冒泡----子元素的同类型事件都会触发父元素的同类型

  4. 如果页面上的事件处理函数过多,会对性能造成影响。

  5. 如果需要让每个li都有点击事件,循环绑定 ---- 页面上实际会有很多的事件处理函数

  6. 循环绑定事件无法给将来的对象绑定事件

  7. 解决方案:使用事件委托

  8. 子元素的事件都会触发父元素的事件

  9. 事件委托的实现:找到所有需要绑定事件的公共的父元素,给父元素绑定事件,然后根据target来判断具体是由谁来触发的