zoukankan      html  css  js  c++  java
  • js事件系列

    以前遇到相关的问题都没在意也没深究,常用到的就一个阻止冒泡event.stopPropagation() 每次连单词都是复制过去的。

    今天找了几篇相关博客看了下算是理清了,特此总结一下也留个备忘。

    先说事件流

    事件流指从页面中接收事件的顺序,有冒泡流和捕获流。

    假如我们点击一个div,实际上是先点击document,然后点击事件传递到div,而且并不会在这个div就停下,div有子元素就还会向下传递,最后又会冒泡传递回document,如下图:

    为了兼容更多的浏览器,一般我们都是把事件添加到在事件冒泡阶段。(IE8及以前只支持事件冒泡)。

    当dom元素注册多个同种事件,事件发生的顺序按照添加的顺序依次触发(IE是相反的)。

    添加和删除事件:

    DOM事件通过addEventListener(添加)和removeEventListener(删除)管理。

    两个方法都一样接收三个参数,第一个是要处理的事件名,第二个是事件处理程序,第三个值为false时表示在冒泡阶段调用处理程序,一般建议在冒泡阶段使用。

    IE则用attachEvent(),detachEvent(),接收两个参数,事件名称和事件处理程序,通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

    事件对象event:

    当触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含了所有与事件有关的信息。

    比如导致事件的元素target,只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完毕,event对象就会被销毁。

    在事件处理程序中this === event.target

    在IE中event参数是未定的,事件对象是作为window的一个属性存在的,因此可以通过window.event来访问event对象,不同于DOM级中event是作为参数直接传入和返回。

    事件冒泡和事件捕获:

    他们是描述事件触发时序问题的术语。

    事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。

    相反事件冒泡是自下而上的去触发事件。

    绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。

    true-事件捕获,false-事件冒泡,默认false,即事件冒泡。

    下面是demo演示冒泡和捕获:

    <div id="parent">
      <div id="child" class="child"></div>
    </div>
    /////////
    document.getElementById("parent").addEventListener("click",function(e){
      alert("parent事件被触发,"+this.id);
    }, false)
    document.getElementById("child").addEventListener("click",function(e){
      alert("child事件被触发,"+this.id)
    }, false)

    上面打印结果:

    child事件被触发,child

    parent事件被触发,parent

    因为第三个参数是false所以是事件冒泡 就会先触发里面dom元素。

    如果改为true则结果相反。

    阻止事件冒泡捕获:

    event.stopPropagation()不能简单说阻止了事件的冒泡,其实也阻止了事件的继续捕获,确切的说应该是阻止事件的进一步传播。

    d1.addEventListener('click', function (event) {
      console.log('d1');
      event.stopPropagation();
    }, true);

    事件委托:

    也可以称为事件代理。用到这个是为了减少不必要的事件处理程序,达到性能优化减少内存的作用。

    用法如下:

    // 相同任务时
    window.onload = function(){
      var oUl = document.getElementById("ul1");
      oUl.onclick = function(ev){
        var ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        if(target.nodeName.toLowerCase() == 'li'){
              alert(123);
             alert(target.innerHTML);
        }
      }
    }

    上面用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的。

    // 不同任务时
    window.onload = function(){
        var oBox = document.getElementById("box");
        oBox.onclick = function (ev) {
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLocaleLowerCase() == 'input'){
                switch(target.id){
                    case 'add' :
                        alert('添加');
                        break;
                    case 'remove' :
                        alert('删除');
                        break;
                    case 'move' :
                        alert('移动');
                        break;
                    case 'select' :
                        alert('选择');
                        break;
                }
            }
        }
        
    }
  • 相关阅读:
    多态的详解
    Java继承详解
    static关键字特点
    数组(相关知识的整理)
    杨辉三角(用for循环)
    Jmeter接口测试案例实践(一)
    组合测试方法:配对测试实践
    用例设计方法:判定表驱动法实践
    sso系统登录以及jsonp原理
    单点登录--sso系统
  • 原文地址:https://www.cnblogs.com/gr07/p/9936354.html
Copyright © 2011-2022 走看看