zoukankan      html  css  js  c++  java
  • JS事件代理

    一步一步来说说事件委托(或者有的资料叫事件代理)

    1. js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。
    2. 事件代理就是,本来加在子元素身上的事件,加在了其父级身上。
    3. 那就产生了问题:父级那么多子元素,怎么区分事件本应该是哪个子元素的?
    4. 答案是:event对象里记录的有“事件源”,它就是发生事件的子元素。
    5. 它存在兼容性问题,在老的IE下,事件源是 window.event.srcElement,其他浏览器是 event.target
    6. 用事件委托有什么好处呢?
    7. 第一个好处是效率高,比如,不用for循环为子元素添加事件了
    8. 第二个好处是,js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便

    --------------------

    好吧,下面还是用例子来说,更容易理解。

    ---------------------

    例子1. 页面有个ul包含着4个li,鼠标移动到li上,li背景变成红色,移出,背景恢复原色。

    如果按照以前的写法,代码如下:

    复制代码
     1         <ul id="ul1">
     2             <li>111</li>
     3             <li>222</li>
     4             <li>333</li>
     5             <li>444</li>
     6         </ul>
     7         
     8         <script type="text/javascript">
     9             window.onload = function(){
    10                 var oUl = document.getElementById('ul1');
    11                 var aLi = oUl.children;
    12                 console.log(aLi);
    13                 
    14                 //传统方法,li身上添加事件,需要用for循环,找到每个li
    15                 for (var i=0;i<aLi.length;i++) {
    16                     aLi[i].onmouseover = function() {
    17                         this.style.background = 'red';
    18                     }
    19                     aLi[i].onmouseout = function(){
    20                         this.style.background = '';
    21                     }
    22                 }//for结束
    23 
    24                 
    25             }
    26         </script>
    复制代码

    现在用事件委托的方式,onmouseover、onmouseout方法要加在ul身上了,再通过找事件源的方式,改变li背景,代码如下:

     上面ul的html代码不变,js部分变为

    复制代码
     1 <script type="text/javascript">
     2             window.onload = function(){
     3                 var oUl = document.getElementById('ul1');                
     4                 oUl.onmouseover = function(ev){
     5                     var ev = ev || window.event;
     6                     var oLi = ev.srcElement || ev.target;
     7                     oLi.style.background = 'red';                    
     8                 }
     9                 
    10                 oUl.onmouseout = function(ev){
    11                     var ev = ev || window.event;
    12                     var oLi = ev.srcElement || ev.target;
    13                     oLi.style.background = '';                    
    14                 }
    15                 
    16             }
    17         </script>
    复制代码

    效果如下:

    但是会发现,鼠标移到了ul身上而不是某个li身上时,获取的事件源是ul,那么整个ul背景将变红,这不是想要的结果,怎么办?

    答曰:加个判断。通过事件源的nodeName判断是不是li,是才做出反应,不是不理它。为了防止nodeName在不同浏览器获取的字母大小写不同,加个toLowerCase()

    所以,上面的js代码更改如下:

    复制代码
     1         <script type="text/javascript">
     2             window.onload = function(){
     3                 var oUl = document.getElementById('ul1');
     4                 
     5                 oUl.onmouseover = function(ev){
     6                     var ev = ev || window.event;
     7                     var oLi = ev.srcElement || ev.target;
     8                     if(oLi.nodeName.toLowerCase() == 'li'){
     9                         oLi.style.background = 'red';
    10                     }
    11                                         
    12                 }
    13                 
    14                 oUl.onmouseout = function(ev){
    15                     var ev = ev || window.event;
    16                     var oLi = ev.srcElement || ev.target;
    17                     if(oLi.nodeName.toLowerCase() == 'li'){
    18                         oLi.style.background = '';
    19                     }                
    20                 }
    21 
    22                 
    23             }
    24         </script>
    25         
    复制代码

    效果如下很完美:

    这就是不用for循环写一堆了,下面再来说说第二个好处:js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便

    上面的文件,假如我再新添加个按钮,点击按钮,ul里就新增加个li,如果用传统的方法,for循环为li添加事件,问题就出现了,最开始有的4个li是有onmouseover和onmouseout事件的,但是后来动态生成的li里没有这两个事件处理函数,因为for循环的时候它还没生成。怎么办呢?只能在按钮点击后,生成li,然后再为生成的li再绑定事件,真是麻烦的很。而事件委托的方式就没事,当后来动态生成的li出现的时候,不用做改变,移到它身上,还是变色的,因为事件是绑定在ul身上的。

  • 相关阅读:
    [Robot Framework] Robot Framework用Execute Javascript对XPath表示的元素执行scrollIntoView操作
    一台机器管理其他都装有kvm的实体机的虚拟机
    阿里云服务器问题
    开发族的跨域问题
    mysql不能连接的原因
    网络命令
    mysql5.7报错端口占用,服务起不来
    nagios的原理及server端跟client端安装配置全部过程
    查看CPU数量和核心数
    iptables的生产场景w
  • 原文地址:https://www.cnblogs.com/xzybk/p/12520759.html
Copyright © 2011-2022 走看看