zoukankan      html  css  js  c++  java
  • 高级事件(二)

       事件委托

       什么是事件委托?用现实中的理解就是:有100个学生同时在某天中午收到快递,但这100个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生。而在jQuery中,我们通过事件冒泡的特性,让子元素绑定的事件冒泡到父元素(或祖先元素)上,然后再进行相关处理即可。

       如果一个企业级应用做报表处理,表格有2000行,每一行都有一个按钮处理。如果用之前的.bind()处理,那么就需要绑定2000个事件,就好比2000个学生同时站在学校门口等
    快递,不但会堵塞路口,还会发生各种意外。这种情况放到页面上也是一样,可能导致页面极度变慢或直接异常。而且2000个按钮使用ajax分页的话,.bind()方法无法动态绑定
    未存在的元素。就好比,新转学的学生,快递员无法验证他的身份,就可能收不到快递。

       有html代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>高级事件</title>
        <script type="text/javascript" src="jquery-1.12.3.js"></script>
        <script type="text/javascript" src="jquery-migrate-1.2.1.js"></script>
        <script type="text/javascript" src="demo.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div style=" 200px; height: 200px; background: green;" id="box">
            <input type="button" class="button" value="按钮" />
        </div>
    </body>
    </html>

       使用.bind()绑定一个事件:

    $(".button").bind("click", function() {
        alert("事件不委托!");
    });

       也可使用.live()绑定一个事件:

    $(".button").live("click", function() {
        alert("事件委托!");
    });

       但要注意:使用live绑定的是document,而非button,所以永远只会绑定一次事件!

       使用.bind()不具备动态绑定功能,只有点击原始按钮才能生成:

    //bind无法动态绑定事件
    $(".button").bind("click", function() {
        $(this).clone().appendTo("#box");
    });

       使用.live()具备动态绑定功能,jQuery1.3使用,jQuery1.7之后废弃,jQuery1.9删除,所以还需引入向下兼容插件——jquery-migrate-1.2.1.js

    //live可以动态绑定事件,因为事件绑定在document上
    $(".button").live("click", function() {
        $(this).clone().appendTo("#box");
    });

       .live()原理就是把click事件绑定到祖先元素$(document)上,而只需要给$(document)绑定一次即可,而非2000次,然后就可以处理后续动态加载的按钮的单击事件。在接受任何事件时,$(document)对象都会检查事件类型(event.type)和事件目标(event.target),如果click事件是.button,那么就执行委托给它的处理程序,.live()方法已经被删除,无法使用了,需要测试使用的话,需要引入向下兼容插件。

       一句话总结:live绑定在document上,而点击button其实是冒泡到document上,并且点击document时候,需要验证event.type和event.target才能触发。

       .live()无法使用链接连缀调用,因为参数的特性导致。即下列代码无效:

    //live是不支持元素连缀调用的
    $("#box").children(0).live("click", function() {
        $(this).clone().appendTo("#box");
    });

       在上面的例子中,我们使用了.clone()克隆。其实如果想把事件行为复制过来,我们只需要传递true即可:.clone(true),这样也能实现类似事件委托的功能,但原理却截然不同,一个是复制事件行为,一个是事件委托,而在非克隆操作下,此类功能只能使用事件委托。

    $(".button").bind("click", function() {
        $(this).clone(true).appendTo("#box"); //其实是复制事件行为
    });

       在非克隆操作下,此类功能只能使用事件委托:

    $(".button").live("click", function() {
        $('<input type="button" class="button" value="按钮" />').appendTo("#box");
    });

       或

    $(".button").live("click", function() {
        $('<input type="button" class="button" value="按钮" />').clone(true).appendTo("#box");
    });

       又或

    $(".button").live("click", function() {
        $('<input type="button" class="button" value="按钮" />').clone().appendTo("#box");
    });

       如果使用.bind()复制事件行为,则无法动态绑定:

    $(".button").bind("click", function() {
        $('<input type="button" class="button" value="按钮" />').clone(true).appendTo("#box");
    });

       当我们需要停止事件委托的时候,可以使用.die()来取消掉。

    $(".button").live("click", function() {
        $(this).clone().appendTo("#box");
    }); 
    $(".button").die("click"); //和unbind一个意思

       由于.live()和.die()在jQuery1.4.3版本中废弃了,之后推出语义清晰、 减少冒泡传播层次、又支持链接连缀调用方式的方法:.delegate()和.undelegate(),但这个方法在 jQuery1.7版本中被.on()方法整合替代了。

    $("#box").delegate(".button", "click", function() {
        $(this).clone().appendTo("#box");
    });
    $("#box").undelegate(".button", "click");

       live的替代方法delegate(),live语义不清晰,由于它没有指定绑定谁,所以不清晰;而delegate语义清晰,绑定谁,谁就在开头。

       支持连缀调用方式:

    $("div").first().delegate(".button", "click", function() {
        $(this).clone().appendTo("div:first");
    });

       注意:.delegate()需要指定父元素,然后第一个参数是当前元素,第二个参数是事件方式,第三个参数是执行函数。和.bind()方法一样,可以传递额外参数,.undelegate()和.unbind()方法一样可以直接删除所有事件,比如:.undelegate('click'),也可以删除命名空间的事件,比如:.undelegate('click.abc')。

       注意:.live()和.delegate()和.bind()方法一样都是事件绑定,那么区别也很明显,用途上遵循两个规则:

    1. 在DOM中很多元素绑定相同事件时
    2. 在DOM中尚不存在即将生成的元素绑定事件时。

       我们推荐使用事件委托的绑定方式,否则推荐使用.bind()的普通绑定。

       on、off和one

       目前绑定事件和解绑的方法有三组共六个。由于这三组的共存可能会造成一定的混乱,为此jQuery1.7以后推出了.on()和.off()方法彻底摒弃前面三组。

       html代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>高级事件</title>
        <script type="text/javascript" src="jquery-1.12.3.js"></script>
        <script type="text/javascript" src="jquery-migrate-1.2.1.js"></script>
        <script type="text/javascript" src="demo.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div style=" 200px; height: 200px; background: green;" id="box">
             <input type="button" class="button" value="按钮" />
        </div>
    </body>
    </html>

       替代.bind()方式:

    $(".button").on("click", function() {
        alert("替代bind");
    });

       替代.bind()方式,并使用额外数据和事件对象:

    $(".button").on("click", {user:'Lee'}, function(e) {
        alert("替代bind" + e.data.user);
    });

       替代.bind()方式,并绑定多个事件:

    $(".button").on("mouseover mouseout", function(e) {
        alert("移入移出");
    });

       替代.bind()方式,以对象模式绑定多个事件:

    $(".button").on({
        mouseover:function() {
            alert("移入");
        },
        mouseout:function() {
            alert("移出");
        }
    });

       又html代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>高级事件</title>
        <script type="text/javascript" src="jquery-1.12.3.js"></script>
        <script type="text/javascript" src="jquery-migrate-1.2.1.js"></script>
        <script type="text/javascript" src="demo.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <form action="123.html">
            <div style=" 200px; height: 200px; background: green;" id="box">
                <input type="submit" class="button" value="按钮" />
            </div>
        </form>
    </body>
    </html>

       替代.bind()方式,阻止默认行为并取消冒泡:

    $("form").on("submit", function() {
        return false;
    });

       或

    $("form").on("submit", false);

       替代.bind()方式,阻止默认行为:

    $('form').on('submit', function (e) {
        e.preventDefault();
    });

       替代.bind()方式,取消冒泡:

    $('form').on('submit', function (e) {
        e.stopPropagation();
    });

       替代.unbind()方式,移除事件:

    $(".button").on("click", function() {
        alert("替代bind");
    });
    $(".button").off("click");

       替代.live()和.delegate(),事件委托:

    $("#box").on("click",".button",function() {
        $(this).clone().appendTo("#box");
    });

       替代.die()和.undelegate(),取消事件委托:

    //替代.live .delegate
    $("#box").on("click",".button",function() {
        $(this).clone().appendTo("#box");
    });
    //移除事件委托
    $("#box").off("click",".button");

       注意:和之前方式一样,事件委托和取消事件委托也有各种搭配方式,比如额外数据、命名空间等等,这里不在赘述。

       不管是.bind()还是.on(),绑定事件后都不是自动移除事件的,需要通过.unbind()和.off()来手工移除。jQuery 提供了.one()方法,绑定元素执行完毕后自动移除事件,one()方法仅触发一次事件。

       类似于.bind()只触发一次:

    //仅一次事件触发
    $(".button").one("click", function() {
        alert("仅一次事件触发");
    });

       类似于.delegate()只触发一次:

    $("#box").one("click",".button",function() {
        $(this).clone().appendTo("#box");
    });
  • 相关阅读:
    element-ui 中dialog居中
    点击element-ui表格中的图标,上方显示具体的文字描述
    第一节:模板模式——需求说明&基本介绍
    第六节:代理模式——总结
    第五节:代理模式——代理模式的变体
    第四节:代理模式——cglib代理
    第三节:代理模式——动态代理
    第二节:代理模式——静态代理
    第一节:代理模式——基本介绍
    第四节:享元模式——总结
  • 原文地址:https://www.cnblogs.com/yerenyuan/p/5429778.html
Copyright © 2011-2022 走看看