☆给DOM元素添加及移除事件监听
给元素绑定事件有三种方法:
1.直接在html元素上绑定事件
2.btnList[i].οnclick=function(){} 此方法移除事件监听应该为this.οnclick=null;
3.addEventListener() 简写方式 事件不带on
下面例子采用第三种方法~

<script>
        window.onload=function(){
            var btnlist=document.getElementsByClassName("btnlist");
            for(var i=0;i<btnlist.length;i++){
                     btnlist[i].addEventListener("click",btnclick);
                    function btnclick(){
                    console.log("hello");
                     this.removeEventListener("click",btnclick);
                }
                
//给对象添加监听事件的时候,回调函数可以是内部函数也可以是外部函数,但如果需要移除监听事件回调函数就必须是外部函数
// 外部函数应该采用一般的有名称的函数的写法 若函数是匿名函数
//                var btndata=function (){
//                console.log(this);
//                this.removeEventListener("click",btndata);  
//                }
//此写法会找不到这个函数(也就不能移除事件监听),因为匿名函数没有名字,removeEventListener的第二参数为函数的名称;

            }
        }
 </script>

<body>
<button class="btnlist">按钮</button>
<button class="btnlist">按钮</button>
<button class="btnlist">按钮</button>
<button class="btnlist">按钮</button>
<button class="btnlist">按钮</button>
</body>

☆事件冒泡
事件冒泡 :是指当给一个元素绑定事件的时候 会把它接收到的事件传给自己的父级,一直到window对象 。下面举例说明:

<style>
        .block{
            width: 200px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            border: 1px solid red;
        }
    </style>
<body>
<div class="block">
    <button class="btn">按钮</button>
</div>
<script>
    var block=document.getElementsByClassName("block")[0];
    var btn=document.getElementsByClassName("btn")[0];
    block.onclick=function(){
        console.log("大");
    }
    btn.onclick=function(){
        console.log("小");
        event.stopPropagation();  //若没有这行脚本,即会产生事件冒泡(点击按钮,控制台小和大都会输出)
    }
</script>
</body>

常见的事件冒泡阻止方式:
       event.stopPropagation(); 阻止事件的冒泡,但不阻止默认行为
       event.preventDefault(); 阻止事件的默认行为,但不阻止事件冒泡
       return false 在原生js里不能阻止事件冒泡及事件默认行为,但在JQuery中两者都可以阻止


事件冒泡只发生在onmouseup、onmousedown、onclick鼠标事件中


☆事件委托
事件委托可以优化代码的性能。
事件委托利用冒泡原理,把事件委托给父级,触发执行效果。举例说明:

<style>
        .menuli{
            list-style: none;
            width: 200px;
            line-height: 35px;
            border: 1px solid black;
            margin: 2px 0;
            text-align: center;
        }
    </style>
    <body>
<ul class="menu">
    <li class="menuli">menu1</li>
    <li class="menuli">menu2</li>
    <li class="menuli">menu3</li>
    <li class="menuli">menu4</li>
</ul>
<script>

//    第一种写法:
//    var menuli=document.getElementsByClassName("menuli");
//    for(var i=0;i<menuli.length;i++){
//        menuli[i].onclick=function(){
//            this.style.backgroundColor="silver";
//        }
//     }

//     第二种写法:
    var menu=document.getElementsByClassName("menu");
    menu[0].onclick=function(event){
        var target=event.target;
        if(target.nodeName.toLowerCase()=="li"){
            target.style.backgroundColor="silver";
        }
    }
</script>
</body>

上例中两种方法可以实现相同的效果,代码长度也差不多,但第二种方法(事件委托)可以提高代码的性能。


提高代码性能的原因:在javaScript中,添加到页面上的事件处理程序将直接关系到页面整体的运行性能。导致这一问题的原因是多方面的。首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能也就越差。其次,必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。事件处理函数过多的解决办法就是采用事件委托,可以提高性能。