• jQuery中事件绑定


    一、前言

         最近在做项目中要用到jQuery来绑定事件,首先想到的是$(selector).事件名();这样绑定事件的方式,这种方式对事件进行绑定其实也就是bind()方法,但当选择器匹配的元素过多,$(selector).事件名();对每个元素进行迭代绑定,会影响性能。除了这种方式可以绑定事件以外,还有live()(已过期)、delegate()、on()方法绑定事件,接下来分析一下它们的区别,以及使用哪种方式最值得推荐。由于live()方法已过期,只分析另外三种,欢迎拍砖、吐槽~~~

    二、用法与区别

    先准备一个example,用于不同方法绑定事件测试与对比。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>on()、delegate()、bind()事件绑定测试</title>
        <link rel="stylesheet" type="text/css" href="bootstrap.css">
    </head>
    <body>
        <div style="800px;margin:50px auto;">
            <botton class="btn btn-success" id="btn">新增一个p元素</botton>
            <p>1</p>
            <p>2</p>
        </div>
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
                $('#btn').click(function(){
                    $('div').append('<p>新增一个p元素</p>');
                });
            });
        </script>
    </body>
    </html>

    接下来对所有的p元素绑定click事件,如:

    bind()方法:为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。

    使用方式 $(selector).bind(event,data,function)

    event  必需。规定添加到元素的一个或多个事件。由空格分隔多个事件。必须是有效的事件。

    data 可选。规定传递到函数的额外数据。

    function 必需。规定当事件发生时运行的函数。

    $('div p').bind('click', function(){
        alert($(this).text());
    });

    这样就为所有的p元素绑定了click事件,当点击后会弹出其内容。但有两个问题,

    第一个问题,这里用了隐式迭代的方法,如果匹配到的元素特别多的时候,比如如果我在div里放了10个p元素,就得执行绑定10次。对于大量元素来说,影响到了性能。
    但是如果是id选择器,因为id唯一,用bind()方法就很快捷了。
    第二个问题,对于尚未存在的元素,无法绑定。点击页面上的按钮,将动态新增一个p元素,点击这个p元素,会发现没有点击响应。

    bind()方法的另外一种写法是:

    $('div p').click(function(){
        alert($(this).text());
    });

    delegate()方法:为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数,使用delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。

    使用方式:$(selector).delegate(childSelector,event,data,function)

    childSelector 必需。规定要附加事件处理程序的一个或多个子元素。

    event 必需。规定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。

    data 可选。规定传递到函数的额外数据。

    function 必需。规定当事件发生时运行的函数。

    $('div').delegate('p', 'click', function(){
         alert($(this).text());
    });

    delegate()方式根据事件委托的机制,不是为p元素直接绑定点击事件,而是为其父元素(或祖先元素)绑定点击事件,当点击任意p元素时,事件会一层层的冒泡,直到绑定事件的元素,在冒泡过程中事件流捕获的对象与选择器匹配时,就会执行这段alert($(this).text());代码。

    所以使用delegate()方法就解决了用bind()方法的上面两个问题,不必为每个p元素绑定事件,也可以为动态新增的p元素绑定事件。虽然绑定是实现了,但是调用的时候也可能出现问题。如果事件目标在DOM树中很深的位置,这样一层层冒泡上来查找与选择器匹配的元素,又影响到性能了。

     

    on() 方法:为指定的元素,添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。使用 on() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。

    使用方式:$(selector).on(event,childselector,data,function)

    event:必需项;添加到元素的一个或多个事件,例如 click,dblclick等;

    childSelector: 可选;需要添加事件处理程序的元素,一般为selector的子元素;

    data:可选;需要传递的参数;

    function:必需;当绑定事件发生时,需要执行的函数;

    $('div').on('click', 'p', function(){
         alert($(this).text());
    });

    on()方法的效果和delegate()方法的效果相同,通过查看jQuery源码你会发现无论bind()还是delegate()其实都是通过on()方法实现的,只是参数不同。三种方法的源码(jQuery source viewer)如下:

           jQuery.fn.bind = function (types, data, fn) {
                return this.on(types, null, data, fn);
            };
    
            jQuery.fn.delegate = function (selector, types, data, fn) {
                return this.on(types, selector, data, fn);
            };
    
            jQuery.fn.on = function (types, selector, data, fn,one) {
                var origFn, type;
    
                // Types can be a map of types/handlers
                if (typeof types === "object") {
                    // ( types-Object, selector, data )
                    if (typeof selector !== "string") {
                        // ( types-Object, data )
                        data = data || selector;
                        selector = undefined;
                    }
                    for (type in types) {
                        this.on(type, selector, data, types[type], one);
                    }
                    return this;
                }
    
                if (data == null && fn == null) {
                    // ( types, fn )
                    fn = selector;
                    data = selector = undefined;
                } else if (fn == null) {
                    if (typeof selector === "string") {
                        // ( types, selector, fn )
                        fn = data;
                        data = undefined;
                    } else {
                        // ( types, data, fn )
                        fn = data;
                        data = selector;
                        selector = undefined;
                    }
                }
                if (fn === false) {
                    fn = returnFalse;
                } else if (!fn) {
                    return this;
                }
    
                if (one === 1) {
                    origFn = fn;
                    fn = function (event) {
                        // Can use an empty set, since event contains the info
                        jQuery().off(event);
                        return origFn.apply(this, arguments);
                    };
                    // Use same guid so caller can remove using origFn
                    fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
                }
                return this.each(function () {
                    jQuery.event.add(this, types, fn, data, selector);
                });
            };

    jQuery官方推荐使用on()绑定事件。

    三、总结

    当选择器匹配到的元素比较多时,不要用bind()迭代绑定,会影响性能;用id选择器时,可以使用bind(),简单便捷;要给动态新增的元素绑定事件时,用delegate()或on(),官方推荐使用on()。

    如需转载本文,请注明来源: http://www.cnblogs.com/changjianqiu/

  • 相关阅读:
    如何更改SQL Server2008默认数据库的存储路径
    虚拟内存页面文件pagefile.sys(棉文件)改变存放位置
    Redis热点数据高频访问问题以及解决方案
    gc日志收集和分析
    oauth2中client_id_to_access数据膨胀问题
    Redis慢查询日志
    24个Jvm面试题总结及答案
    springboot-使用assembly进行项目打包
    volatile关键字解读
    redis的zset结构跳表
  • 原文地址:https://www.cnblogs.com/changjianqiu/p/4676544.html
Copyright © 2020-2023  润新知