• jQuery之on


    在jQuery1.9版本中,已经去掉了live和delegate方法,从而将on方法的地位进一步提升。

    jQuery如此推崇on方法,必有其牛逼的地方。那么我们就有必要了解这个on,并在代码中利用它,从而优化代码和提高性能。

    一、on之基本使用方法

    注:在jQuery1.7后,on方法就可以全面绑定任何事件了。

    .on( events [,selector] [,data] ,handler)

      event:为事件类型,可以有多个事件类型。

      selector:可选,过滤绑定在on方法上的后代元素。注:如果有selector,on方法是采用事件代理,这样可以提升代码性能。

      data:可选,当事件被触发时,它会传给event.data,从而可以加以利用

      handler:当事件被触发时,执行的方法。

    下面写个demo,看看on的使用:

    //当p元素的click事件,被触发时,弹出p元素的文本信息
    $('p').on('click',function(){
        alert( $(this).text() );
    });
    //在上面的基础上,传值给p元素
    $('p').on('click',{foo:"bar"},function(event){
        alert( event.data.foo );
    });
    二、on之事件代理

    标准浏览器中都有事件冒泡(bubble)或捕获(propagate)机制(除IE)。

    如下图:

    --当目标元素被触发时,它的流程是,先从它祖先元素一层一层,跋山涉水将事件传达给目标函数,如上图中P的父元素 à target的父元素P à target,此为事件捕获

    --当目标函数被触发后,又将事件一层一层传递到根节点,即老祖宗,此为事件冒泡

    所有浏览器都有事件冒泡机制。所以,我们可以利用这一特性,优化代码,减少事件绑定。

    on方法也利用了这一特性。当‘selector’被提供时,就是事件委托,事件触发时,直接绑定在on方法上的元素是不会触发该事件,而它指定的后代元素‘selector’就会利用冒泡机制,到直接绑定在on方法上的元素,给予处理。

    举个例子,我们在写导航栏时,经常用到ul+li这种方式,当点击每一个li时,页面相应切换,没有经验的做法嘛,就是将每个li绑定一个click嘛。

    那么,问题来了。没过几天,突然我发现有几个li的模块其实可以整合到一起的,怎么办呢?删除原来为li添加的事件,再重新写过?

    没过几天,假设有新需求来,我要加两个模块呢?

    假如你用的是jQuery框架,完全可以在最开始用on方法嘛,利用事件委托其特性,一键搞定。

    如下:

    function doSomething(){
        console.log(this);
    }
    $('ul').on('click','li',doSomething/*在这里,doSomething方法中this指向的是li*/);

    注:on方法中当selector有值时,虽然采用的冒泡机制,但this指向的是目标元素对象。

    如:

    function doSomething(event,name){
        //结果为true
        console.log( event.target === this );
    }
    $('ul').on('click','li',doSomething);
    三、on之false

    在on方法中,如果你想阻止事件冒泡又想阻止默认事件行为,你可以采用快捷方式,直接false。

    如表单提交:

    $('form').on('submit',false);
    四、on之data

    .on( events [,selector] [,data] ,handler)

    当data有值且不为null或者undefined,事件被触发时,它会被传给event.data。

    但,请注意,当你传入data的值后,它是恒定不变的。什么意思?

    看看下面的demo:

    <!DOCTYPE html> 
        <head>
            <title>on</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            <style>
                ul{
                    overflow:hidden;
                }
                ul li{
                    float:left;
                    margin-left:10px;
                    list-style-type:none;
                }
            </style>
        </head>
        <body>
            <ul>
                <li>item1</li>
                <li>item2</li>
            </ul>
            <!--需要自行引入jquery-->
            <script src="jquery-1.12.0.js"></script>
            <script>
                var name = 'monkey';
                /*5秒后将name的值变成'dorie'*/
                setTimeout(function(){
                    name = 'dorie';
                    console.log('after setTimeout: ' + name);
                },5000);
                //打印event.data.msg
                function doSomething(event){
                    console.log(event.data.msg);
                };
                //msg:name,即msg:'monkey'
                $('ul').on('click','li',{msg:name},doSomething);
            </script>
        </body>
    </html>

    运行代码后的结果:

    我们不但可以这样在绑定元素事件的时候赋予data值,我们还可以用.trigger()或者.triggerHandler()来传递值哦,只需要在触发方法(如下的doSomething)中再加入一个参数哈。

    如下:

    /*第一个参数当然是用来接收event的哈*/
    function doSomething(event,name){
        console.log(name);
    }
    $('ul').on('click','li',doSomething);
    /*here trigger*/
    $('li').trigger('click','monkey');

    那如果我想利用trigger传入两个或者多个值呢?是不是再加入几个参数呢?

    不太对,我们先看看下面的代码:

    <!DOCTYPE html> 
        <head>
            <title>on</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            <style>
                ul{
                    overflow:hidden;
                }
                ul li{
                    float:left;
                    margin-left:10px;
                    list-style-type:none;
                }
            </style>
        </head>
        <body>
            <ul>
                <li>item1</li>
            </ul>
            <script src="jquery-1.12.0.js"></script>
            <script>
                /*传入两个参数name、age*/
                function doSomething(event,name,age){
                    console.log(name);
                    console.log(age);
                }
                $('ul').on('click','li',doSomething);
                $('li').trigger('click','monkey',100);
            </script>
        </body>
    </html>

    运行代码结果如下:

    so,那怎么办呢?

    有两个方法,可以达到你的目的。

    方法一,参数不变,trigger传入值时,传入一个数组,数组中的值与参数一一对应就好了。

    function doSomething(event,name,age){
        console.log(name);
        console.log(age);
    }
    $('ul').on('click','li',doSomething);
    //trigger传入对应数组
    $('li').trigger('click',['monkey',100]);

    方法二,参数和trigger传入方式皆改变。都传入对象嘛,不就只需要一个参数了么。

    function doSomething(event,obj){
        console.log(obj.name);
        console.log(obj.age);
    }
    $('ul').on('click','li',doSomething);
    $('li').trigger('click',{name:'monkey',age:100});
    五、其他

    ‘hover’在jQuery1.9中被移除了(注意是’hover’,而不是.hover()),所以on方法是无法调用hover的,

    如下:

    那如果我想利用on方法来实现hover的‘事件代理’呢?

    怎么办呢?‘hover’都不存在了!!!

    其实它一直都不在,只是’mouseenter’和’mouseleave’的快照(shorthand)而已。

    所以,我们可以利用event.type来处理。

    如下:

    $('ul').on('mouseenter mouseleave','li',function(event){
        if( event.type == 'mouseenter' ){
            //相应处理    
        }
        else if(event.type == 'mouseleave'){
            //相应处理    
        }
    });    

    另外,当我利用on为同一个事件,绑定了多个执行方法时,它会依次执行,如下:

    <!DOCTYPE html> 
        <head>
            <title>on</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            <style>
                ul{
                    overflow:hidden;
                }
                ul li{
                    float:left;
                    margin-left:10px;
                    list-style-type:none;
                }
            </style>
        </head>
        <body>
            <ul>
                <li>item1</li>
            </ul>
            <script src="jquery-1.12.0.js"></script>
            <script>
                $('li').on('click',function(){
                    console.log('1');
                });
                $('li').on('click',function(event){
                    console.log('2');
                });
                $('li').on('click',function(){
                    console.log('3');
                });
            </script>
        </body>
    </html>

    运行后的结果:

    倘若,我只想执行1、2,但是不想执行第三个click,输出‘3’呢?

    我们可以利用event.stopImmediatePropagation()

    作用:阻止剩余的事件处理函数的执行,并阻止当前事件冒泡。

    $('li').on('click',function(){
        console.log('1');
    });
    $('li').on('click',function(event){
        console.log('2');
        event.stopImmediatePropagation();
    });
    $('li').on('click',function(){
        console.log('3');
    });

    在上面大家也看见了,用on为同一个元素添加同一个事件时,事件是不会被覆盖掉的,所以,为了避免代码干扰,我们可以这样绑定事件:

    $('li').off('click').on('click',doSomething);

    我们利用.off()还可以取消掉指定函数名的事件哦,而不是同一事件一切清空,前提是我们使用的是函数名。

    如下:

    像上面那样,我们就可以清除方法名为one的click事件。

    由于$(obj).click(dosomething)是$(obj).on(‘click’,dosomething)的快照(shorthand),所以.()off同样适用于它.click()。

    好了,时间也不早了。晚安,everyone~

  • 相关阅读:
    json转成csv文件
    从输入url到页面展示到底发生了什么
    详解定时任务中的 cron 表达式
    创建型模式之简单工厂模式
    MySQL数据分组GROUP BY 和HAVING
    贪心算法
    JavaScript与DOM(下)
    JavaScript与DOM(上)
    Hibernate 的一级缓存和二级缓存总结
    JVM 发生OOM的四种情况
  • 原文地址:https://www.cnblogs.com/giggle/p/5365421.html
Copyright © 2020-2023  润新知