zoukankan      html  css  js  c++  java
  • JavaScript事件冒泡和事件委托

    JavaScript事件冒泡和事件委托

    接触JavaScript不久,学的东西也不是特别多。小雨就是习惯把平时学到的东西拿出来分享。一方面加强自己的印象,一方面可以让自己的经验为他人答疑解惑。我们知道JavaScript可以监控页面上元素的各种事件,常用的事件有很多,例如点击,鼠标移入、移出,元素改变等等。这次主要说一下事件冒泡及其一个比较酷的应用,事件委托。不做特殊说明,以下都在jQuery框架内执行。

    事件冒泡

    什么是“事件冒泡”呢?假设这里有一杯水,水被用某种神奇的方式分成不同颜色的几层。这时,从最底层冒出了一个气泡,气泡会一层一层地上升,直到最顶层。而你不管在水的哪一层观察都可以看到并捕捉到这个气泡。好了,把“水”改成“DOM”,把“气泡”改成“事件”。这就是“事件冒泡”。

    为了可以直观地观察到这一现象,我写了一个小程序。这个页面中一共有4个嵌套的正方形。最大的那个在最顶层,最小的那个在最底层。我为每一层都单独绑定了一个点击事件,当这一层被点击时,会为这层涂色。试试看,点击最小的正方形会发生什么?点击其他的又会发生什么呢? (点击这里查看demo)

    CSS

    .white{background-color:#fff;}
    #d1{width:400px;height:400px;border:1px solid #000;margin:50px 50px;}
    #d2{width:300px;height:300px;border:1px solid #000;margin:50px 50px;}
    #d3{width:200px;height:200px;border:1px solid #000;margin:50px 50px;}
    #d4{width:100px;height:100px;border:1px solid #000;margin:50px 50px;}
    

    HTML

    <div id="d1" class="white">
        <div id="d2" class="white">
            <div id="d3" class="white">
                <div id="d4" class="white"></div>
            </div>
        </div>
    </div>
    <button id="reset1">重置</button>
    

    Javascript

    jQuery('#d4').click(function(){jQuery(this).css('background-color', 'yellow')});
    jQuery('#d3').click(function(){jQuery(this).css('background-color', 'green')});
    jQuery('#d2').click(function(){jQuery(this).css('background-color', 'blue')});
    jQuery('#d1').click(function(){jQuery(this).css('background-color', 'red')});
    jQuery('#reset1').click(function(){jQuery('.white').css('background-color', '#fff')});
    

    没错,点击最小的那个,外面所有的都会被上色。你会发现,点击里层的正方形,外层所有的正方形都会被上色。因为它们也都捕捉到了点击事件。看,他们抓到“气泡”了!

    事件委托

    上一节的例子我们做一点小小的修改。气泡带上了某种信息,会告诉其经过的每一层自己是在哪一层产生的。JavaScript的事件确实会带着这个属性。当程序捕获一个事件的时候,它会知道这个事件来自于页面上哪个元素。修改上面的程序,使用事件委托来处理点击事件。当最顶层捕获点击事件时,查看事件来源于哪一层,然后只将那一层涂色。再次点击每一层,查看实际效果。只有当前点击的正方形变色了,其他的都毫无反应。(点击这里查看demo)

    jQuery('#d1').click(function(e){
            var t = jQuery(e.target);
            var id = t.attr('id');
            if (id==='d4'){
                    t.css('background-color', 'yellow');
            } else if (id==='d3') {
                    t.css('background-color', 'green');
            } else if (id==='d2') {
                    t.css('background-color', 'blue');
            } else {
                    t.css('background-color', 'red');
            }
    });
    

    当然,如果你有这样嵌套的页面元素,使用了事件委托,委托到了最顶层,这时需要注意:如果其中某个元素,你不希望它的事件冒泡,那么可以使用某种方式阻止事件的冒泡。在jQuery框架中,可以使用stopPropagation()方法来实现而不必关心浏览器兼容性。

    $('#bind').click(function(){
        if ($(this).is(':checked')) {
            $('#d4').bind('click', function(e){
                e.stopPropagation();
                alert('冒泡被阻止,这块将不会改变颜色');
            });
        } else {
            $('#d4').unbind('click');
        }
    });
    

    重置后选中“阻止最小的方块的事件冒泡”,再点击最小的方块,看是否变色。显然是不会变色,阻止了冒泡,父层将无法接收到点击事件。

    注意事项

    事件委托是事件冒泡的一个应用,可以减少绑定元素的个数,也不必担心子节点被替换后可能需要进行重新的事件绑定。因为事件的捕获和后续代码的执行已经完全委托给了其父节点。如果页面中含有大量元素需要绑定事件,这样做会减少事件绑定数量,为浏览器减负,无疑会提高页面性能。

    但也有些需要注意的。如果用于捕获事件的节点会在某些情况下return false,而你的一个点击事件未委托给父节点,那么,你可能需要阻止这个节点的事件冒泡来达到正确的目的。例如:我在一个div里面有一些按钮和其他元素。利用事件委托来处理这些按钮的点击,如果不是按钮则return false。这时,错误就出现了。如果其他元素中含有链接,那么链接的点击事件也会被委托给div。然而点击链接,会没有任何反应。解决办法一是在委托的代码中对链接进行处理,二是阻止链接的事件冒泡。

    转载:http://www.pureweber.com/article/event-delegation/

  • 相关阅读:
    动态规划
    Python第二天学习
    Python第一天学习---基础语法
    java易错知识点
    C语言---指针复习
    排序汇总
    课程设计---创建族谱管理系统
    Vue第五篇 Vue的生命周期
    Vue第四篇 Vue路由系统
    Vue第三篇 Vue组件
  • 原文地址:https://www.cnblogs.com/shamgod/p/4597848.html
Copyright © 2011-2022 走看看