jQuery事件

jQuery基础事件
JavaScript有一个非常重要的功能,就是事件驱动。当页面完全加载后,用户通过鼠标或键盘触发页面中绑定事件的元素即可触发。jQuery为开发者更有效率的编写事件行为,封装了大量有益的事件方法供我们使用。
一.绑定事件
在JavaScript中,常用的事件有:click、dblclick、mousedown、mouseup、mousemove、mouseover、mouseout、change、select、submit、keydown、keypress、keyup、blur、focus、load、resize、scroll、error。
jQuery通过.bind()方法来为元素绑定这些事件。可以传递三个参数:bind(type,[data],fn),type表示一个或多个类型的事件名字符串;[data]是可选的,作为event.data属性值传递一个额外的数据,这个数据是一个字符串、一个数字、一个数组或一个对象;fn表示绑定到指定元素的处理函数。

<body>
<form>
<input type="button" value="按钮" />
</form>
</body>

使用点击事件通过.bind封装
第一种方式:匿名函数

$(function () { 
   $('input').bind('click', function () {    //点击按钮后执行匿名函数
        alert('弹窗!');     
    });
}); 

第二种方式:普通处理函数

$(function () { 
    $('input').bind('click',fn);            //执行普通函数式无须圆括号
    function fn() {
        alert('处理函数!')   
    }
}); 

第三种方式:可以同时绑定多个事件
(1)鼠标移到执行事件1弹出当点击执行事件2

$(function () { 
    $('input').bind('click mouseover', function () {
        alert('弹窗!');
    });
}); 

~~~

<body>
<input type="button" value="按钮" />
<div></div>
</body>

(2)当鼠标移入到按钮上显示1,离开按钮又显示一个1

$(function () { 
    $('input').bind('mouseover mouseout',function () {   //移入和移出分别执行一次
        $('div').html(function (index,value) {
            return value + '1';
        });
    });
}); 

通过对象键值对绑定多个参数
当鼠标移入到按钮上显示移,离开按钮又显示移出

$(function () { 
    $('input').bind({                   //传递一个对象
        mouseover : function () {       //事件名的引号可以省略
            alert('移入');
        },
        mouseout : function () {
            alert('移出');
        }
    });
}); 

使用unbind删除绑定的事件

$(function () { 
    $('input').bind('click mouseover', function () {
        alert('弹窗!');
    });
    $('input').unbind();        //删除全部事件
}); 

使用unbind参数删除指定类型事件
当鼠标移入到按钮上mouseover事件弹出保留,点击按钮click事件删除

$(function () { 
    $('input').bind('click mouseover', function () {
        alert('弹窗!');
    });
    $('input').unbind('click');          //只删除click事件
}); 

使用unbind参数删除指定处理函数的事件
俩个事件fn1和fn2只删除fn2的事件

$(function () { 
    $('input').bind('click',fn1);
    $('input').bind('click',fn2);
    
    function fn1() {
        alert('fn1');
    }
    
    function fn2() {
        alert('fn2');
    }
    
    $('input').unbind('click',fn2);  //删除click事件绑定了fn2的
}); 

二.简写事件
为了使开发者更加方便的绑定事件,jQuery封装了常用的事件以便节约更多的代码。我们称它为简写事件。
1.简写事件绑定方法
鼠标触发
(1)click(fn)鼠标触发每一个匹配元素的click(单击)事件

$(function () { 
    $('input').click(function () {
        alert('单击');
    });
}); 

(2)dblclick(fn)鼠标 触发每一个匹配元素的dblclick(双击)事件

$(function () { 
    $('input').dblclick(function () {
        alert('双击');
    });
}); 

(3)mousedown(fn)鼠标触发每一个匹配元素的mousedown(点击后)事件

$(function () { 
    $('input').mousedown(function () {
        alert('鼠标左键按下');
    });
}); 

(4)mouseup(fn)鼠标触发每一个匹配元素的mouseup(点击弹起)事件

$(function () { 
    $('input').mouseup(function () {
        alert('鼠标左键按下弹起');
    });
}); 

.mouseover()和.mouseout()表示鼠标移入和移出的时候触发。那么jQuery还封装了另外一组:.mouseenter()和.mouseleave()表示鼠标穿过和穿出的时候触发。.mouseenter()和.mouseleave()这组穿过子元素不会触发,而.mouseover()和.mouseout()则会触发。
(5-6html代码)

<body>
<div style="width:200px;height:200px;background:green;">
</div>
</body>

(5)mouseover(fn)鼠标触发每一个匹配元素的mouseover(鼠标移入)事件
(6)mouseout(fn)鼠标触发每一个匹配元素的mouseout(鼠标移出)事件
当鼠标移入里变为红色,当鼠标移出时返回成绿色

$(function () { 
    $('div').mouseover(function () {
        $(this).css('background', 'red');
    }).mouseout(function () {
        $(this).css('background', 'green');
    }); 
});

(7-9html代码)

<body>
<div style="width:200px;height:200px;background:green;">
    <p style="width:100px;height:100px;;background:red;"></p>
</div>
<strong></strong>
</body>

(7)mousemove(fn)鼠标 触发每一个匹配元素的mousemove(鼠标移动)事件
当鼠标移入里变为红色,当鼠标移出时返回成绿色
over会触发子节点

$(function () { 
    $('div').mouseenter(function () {
        $(this).css('background', 'red');
    }).mouseleave(function () {
        $(this).css('background', 'green');
    });
    
    $('div').mouseover(function() {                    //over会触发子节点
        $('strong').html(function (index, value) {
            return value + '1';
        });
    });
});

(8)mouseenter(fn)鼠标 触发每一个匹配元素的mouseenter(鼠标穿过)事件

$(function () { 
    $('div').mouseenter(function () {
        $(this).css('background', 'red');
    }).mouseleave(function () {
        $(this).css('background', 'green');
    });
    
    $('div').mouseenter(function() {                //enter不会触发子节点
        $('strong').html(function (index, value) {
            return value + '1';
        });
    });
}); 

(9)mouseleave(fn)鼠标 触发每一个匹配元素的mouseleave(鼠标穿出)事件
mouseleave在里面不会触发任何节点,完全离开div区域产生触发

$(function () { 
    $('div').mouseenter(function () {
        $(this).css('background', 'red');
    }).mouseleave(function () {
        $(this).css('background', 'green');
    });
    
    $('div').mouseleave(function() {                    
        $('strong').html(function (index, value) {
            return value + '1';
        });
    });
}); 

键盘:

<body>
<input type="text" value="" />
</body>

(1)keydown(fn)键盘触发每一个匹配元素的keydown(键盘按下)事件
当键盘按下任何键位弹出对话框

$(function () { 
    $('input').keydown(function () {
        alert('键盘');
    });
}); 

(2)keyup(fn)键盘触发每一个匹配元素的keyup(键盘按下弹起)事件
当键盘按下任何键位松开时弹出对话框

$(function () { 
    $('input').keyup(function () {
        alert('键盘');
    });
}); 

(3)keypress(fn)键盘 触发每一个匹配元素的keypress(键盘按下)事件
当键盘按下任何键位弹出对话框返回的对应的值字符编码

$(function () { 
    $('input').keydown(function (e) {
        alert(e.keyCode);
    });
}); 

注意:e.keyCode和e.charCode在两种事件互换也会产生不同的效果,除了字符还有一些非字符键的区别。更多详情可以了解JavaScript事件处理那章。
文档:
(1)unload(fn)文档当卸载本页面时绑定一个要执行的函数

$(function () { 
   $(window).unload(function () {      //一般unload卸载页面新版浏览器应该是不支持的,获取要设置一个。
        alert('1');                    //刷新弹出1。一般用于清理工作。 
    });
}); 

(2)resize(fn)文档触发每一个匹配元素的resize(文档改变大小)事件
窗口大小改变弹出

$(function () { 
   $(window).resize(function () {            
        alert('文档改变了');                                    
    });
}); 

(3)scroll(fn)文档触发每一个匹配元素的scroll(滚动条拖动)事件
滚动条拖动弹出

$(function () { 
    $(window).scroll(function () {            
        alert('滚动条改变了');                                    
    });
}); 

.focus()和.blur()分别表示光标激活和丢失,事件触发时机是当前元素。而.focusin()和.focusout()也表示光标激活和丢失,但事件触发时机可以是子元素。

<body>
<body>
<input type="text" value="" />
</body>

(4)focus(fn)表单触发每一个匹配元素的focus(焦点激活)事件

<body>
<div style="width:200px;height:200px;background:green;">
    <input type="text" value="" />
</div>
</body>

当光标点击文档里弹出

$(function () { 
    $('input').focus(function () {                      //focus必须是当前元素才能激活
        alert('光标激活');
    });
}); 

(5)blur(fn)表单触发每一个匹配元素的blur(焦点丢失)事件

$(function () {
    $('input').blur(function () {                       //blur必须是当前元素才能激活
        alert('光标丢失');
    });
}); 

(6)focusin(fn)表单触发每一个匹配元素的focusin(焦点激活)事件

$(function () { 
    $('div').focusin(function () {            //focusin可以是子元素激活  
        alert('光标丢失');
    });
});

(7)focusout(fn)表单触发每一个匹配元素的focusout(焦点丢失)事件

$(function () { 
    $('div').focusout(function () {             //focusout可以是子元素激活  
        alert('光标丢失');
    });
}); 

注意:.blur()和.focusout()表示光标丢失,和激活类似,一个必须当前元素触发,一个可以是子元素触发。
(8)select(fn)表单触发每一个匹配元素的select(文本选定)事件

<body>
<input type="test" value="文本" />
</body>

选定文本的时候触发事件弹出

$(function () { 
    $('input').select(function () {
        alert('文本选定');
    });
}); 

change(fn)表单触发每一个匹配元素的change(值改变)事件
文本内容改变的时候触发事件弹出

$(function () { 
    $('input').change(function () {
        alert('文本改变');
    });
}); 

submit(fn)表单触发每一个匹配元素的submit(表单提交)事件

<body>
<form>
<input type="submit" value="文本" />
</form>
</body>

当点击提交文本时触发

$(function () { 
    $('form').submit(function () {
        alert('表单提交!');
    });
}); 

三.复合事件
jQuery提供了许多最常用的事件效果,组合一些功能实现了一些复合事件,比如切换功能、智能加载等。
(1)ready(fn)当DOM加载完毕触发事件
(2)hover([fn1,]fn2)当鼠标移入触发第一个fn1,移出触发fn2
当鼠标移入变为红色移除变为绿色

$(function () { 
    $('div').hover(function () {
        $(this).css('background', 'red');
    }, function () {
        $(this).css('background', 'green');
    });
}); 

注意:.hover()方法是结合了.mouseenter()方法和.mouseleva()方法,并非.mouseover()和.mouseout()方法。
(3)toggle(fn1,fn2[,fn3..]) 已废弃,当鼠标点击触发 fn1,再点击触发 fn2...
.toggle()这个方法比较特殊,这个方法有两层含义,第一层含义就是已经被 1.8 版废用、1.9 版删除掉的用法,也就是点击切换复合事件的用法。第二层函数将会在动画那章讲解到。既然废弃掉了,就不应该使用。被删除的原因是:以减少混乱和提高潜在的模块化程度。
但你又非常想用这个方法,并且不想自己编写类似的功能,可以下载jquery-migrate.js文件,来向下兼容已被删除掉的方法。
注意:由于官方已经删除掉这个方法,所以也是不推荐使用的,如果在不基于向下兼容的插件JS。我们可以自己实现这个功能。
当点击鼠标分别变换成红色,蓝色,绿色

$(function () { 
    var flag = 1;
    $('div').click(function () {
        if (flag == 1) {
            $(this).css('background', 'red');
            flag = 2;
        } else if (flag == 2) {
            $(this).css('background', 'blue');
            flag = 3;
        } else if (flag == 3) {
            $(this).css('background', 'green');
            flag = 1;
        }
    });
}); 

jQuery事件对象
JavaScript 在事件处理函数中默认传递了event对象,也就是事件对象。但由于浏览器的兼容性,开发者总是会做兼容方面的处理。jQuery在封装的时候,解决了这些问题,并且还创建了一些非常好用的属性和方法。
一.事件对象
事件对象就是event对象,通过处理函数默认传递接受。之前处理函数的e就是event事件对象,event对象有很多可用的属性和方法

$(function () { 
    $('input').bind('click', function (e) {  //接受事件对象参数
        alert(e);                            //返回属性和方法:[object Object]
    });
}); 

(1)type获取这个事件的事件类型的字符串,例如:click

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.type);                       //返回:click(类型是string)
    });
}); 

(2)target获取触发事件的DOM元素

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.target);                     //[object HTMLInputElement]
    });
});

注意:target是获取触发元素的DOM,触发元素,就是你点了哪个就是哪个
(3)data获取事件调用时的额外数据
点击按钮得到数字123

$(function () { 
    $('input').bind('click', 123, function (e) {
        alert(e.data);
    });
}); 

点击按钮得到字符串abc

$(function () { 
    $('input').bind('click', 'abc', function (e) {
        alert(e.data);
    });
}); 

点击按钮得到数组里的a

$(function () { 
    $('input').bind('click', [1,2,3,'a','b'], function (e) {
        alert(e.data[3]);        //a
    });
}); 

点击按钮得到对象age里的100

$(function () { 
$('input').bind('click', {user : 'xixi', age : 100}, function (e) {
        alert(e.data.age);         //100
    });
}); 

(4)relatedTarget获取移入移出目标点离开或进入的那个DOM元素

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.relatedTarget);    //null
    });
}); 

(5)currentTarget 获取绑定前触发的 DOM元素,等同与this

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.currentTarget);
    });
}); 

注意:currentTarget得到的是监听元素的DOM,而this也是得到监听元素的DOM。你绑定的哪个就是那个
(6)pageX/pageY获取相对于页面原点的水平/垂直坐标
(7)screenX/screenY获取显示器屏幕位置的水平/垂直坐标(非jQuery封装)
(8)clientX/clientY获取相对于页面视口的水平/垂直坐标(非jQuery封装)
X轴

$(function () { 
    $(document).bind('click', function (e) {
        alert(e.pageX + ',' + e.screenX + ',' + e.clientX);  //32,32,32
    });
});

Y轴

$(function () { 
    $(document).bind('click', function (e) {
        alert(e.pageY + ',' + e.screenY + ',' + e.clientY);   //310,462,310
    });
}); 

(9)result获取上一个相同事件的返回值

$(function () { 
    $('input').bind('click', function (e) {
        return 123;
    });

    $('input').bind('click', function (e) {
        alert(e.result);
    });
}); 

(10)timeStamp获取事件触发的时间戳(适合比较和存储)

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.timeStamp);
    });
}); 

(11)which获取鼠标的左中右键(1,2,3),或获取键盘按键

$(function () { 
    $('input').bind('mousedown', function (e) {
        alert(e.which);
    });
}); 

(12)altKey/shiftKey和ctrlKey/metaKey获取是否按下了alt、shift、ctrl(这三个非jQuer 封装)或meta键(IE原生meta键,jQuery做了封装)
按下ctrl键点击按钮会显示true

$(function () { 
    $('input').bind('click', function (e) {
        alert(e.ctrlKey);
    });
}); 

二.冒泡和默认行为
1.如果在页面中重叠了多个元素,并且重叠的这些元素都绑定了同一个事件,那么就会出现冒泡问题。
禁止冒泡
HTML页面

<body>
<div style="width:200px;height:200px;background:#ccc;">
    <input type="button" value="按钮" />
</div>
</body>

三个不同元素触发事件阻止冒泡

$(function () { 
    //冒泡和阻止冒泡
    $('input').click(function (e) {
        e.stopPropagation();                //禁止冒泡
        alert('input');
    });
    
    $('div').click(function (e) {
        e.stopPropagation();    
        alert('div');
    });
    
    $(document).click(function () {
        alert('document');
    });
}); 

注意:当我们点击文档的时候,只触发文档事件;当我们点击div层时,触发了div和文档两个;当我们点击按钮时,触发了按钮、div 和文档。触发的顺序是从小范围到大范围。这就是所谓的冒泡现象,一层一层往上。
2.冒泡和默认行为的一些方法:
(1)preventDefault()取消某个元素的默认行为
阻止默认行为
HTML页面

<body>
<div style="width:200px;height:200px;background:#ccc;">
    <input type="button" value="按钮" />
    <a href="http://www.baidu.com" target="_blank">百度<a>
</div>
</body>

点击百度弹出baidu.com阻止默认行为不跳转到http://www.baidu.com

$(function () { 
    $('a').click(function (e) {
        e.preventDefault();                //阻止默认行为
        alert('baidu.com');
    });
}); 

组织表单提交
HTML页面

<body>
<form action="http://www.baidu.com">
<div style="width:200px;height:200px;background:#ccc;">
    <input type="submit" value="按钮" />
</div>
</form>
</body>

点击按钮弹出表单提交但禁止跳转到http://www.baidu.com
方式一:

$(function () { 
    //禁止表单提交
    $('input').click(function (e) {    
        e.preventDefault();
        alert('表单提交');
    });
}); 

方式二:不弹窗组织表单提交

$(function () { 
    //禁止表单提交
    $('form').submit(function (e) {
        e.preventDefault();
    });
}); 

注意:如果想让上面的超链接同时阻止默认行为且禁止冒泡行为,可以把两个方法同时写上:event.stopPropagation()和event.preventDefault()。这两个方法如果需要同时启用的时候,还有一种简写方案代替,就是直接return false。
return false阻止冒泡又禁止了默认行为

$(function () { 
    //阻止冒泡又禁止了默认行为
    $('a').click(function (e) {
        alert('baidu.com');
        return false;
    });
    
    $('div').click(function () {
        alert('div');
    });
    
    $(document).click(function () {
        alert('document');
    });
}); 

(3)isDefaultPrevented()判断是否调用了preventDefault()方法
判断是否设定了冒泡和禁止默认行为
方式1:

$(function () { 
    $('a').click(function (e) {
        e.preventDefault();
        e.stopPropagation();
        alert(e.isDefaultPrevented());     //true
        alert(e.isPropagationStopped());    //true
    });
}); 

方式2:

$(function () { 
    $('a').click(function (e) {
        e.preventDefault();
        e.stopPropagation();
    });
    $('a').click(function (e) {
        alert(e.isDefaultPrevented());
        alert(e.isPropagationStopped());
    });
}); 

(4)stopImmediatePropagation()取消事件冒泡,并取消该事件的后续事件处理函数
(5)isImmediatePropagationStopped()判断是否调用了stopImmediatePropagation()方法

$(function () { 
    $('a').click(function (e) {
        e.stopImmediatePropagation();               //
        alert(e.isImmediatePropagationStopped());   //判断是否执行了stopImmediatePropagation()方法返回:true
        alert('a1');                                //返回:a1
    });
    //后面的就不执行了直接跳转
    $('a').click(function (e) {
        alert('a2');
    });
    
    $('div').click(function (e) {
        alert('div');
    });
    
    $(document).click(function () {
        alert('document');
    });
}); 

jQuery高级事件
jQuery不但封装了大量常用的事件处理,还提供了不少高级事件方便开发者使用。比如模拟用户触发事件、事件委托事件、和统一整合的on和off,以及仅执行一次的one方法。这些方法大大降低了开发者难度,提升了开发者的开发体验。
一.模拟操作
在事件触发的时候,有时我们需要一些模拟用户行为的操作。例如:当网页加载完毕后自行点击一个按钮触发一个事件,而不是用户去点击。

<body>
<input type="button" value="按钮" />
</body>

当浏览器打开的时候去自发的点击button执行了这段话
方式一:

//点击按钮事件
$(function () { 
    $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    });    
    //模拟用户点击操作
    $('input').trigger('click');         //input元素要被模拟,模拟click点击事件
});

方式二:

$(function () { 
    $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).trigger('click');
});

有时在模拟用户行为的时候,我们需要给事件执行传递参数,这个参数类似与event.data的额外数据,可以可以是数字、字符串、数组、对象。
trigger额外数据参数传字符串:123和abc分别对应data1,data2刷新后弹出123 | abc

$(function () { 
    $('input').click(function (e, data1,data2) {
        alert(data1 + '|' + data2);
    }).trigger('click', ['123','abc']);    
});
//trigger额外数据,只有一条的时候,可以省略中括号,多条不能省略,第二条之后就无法识别了

trigger额外数据参数传数组:

$(function () { 
    $('input').click(function (e, data1, data2, data3, data4) {
        alert(data1 + '|' + data2 + '|' + data3[1] + '|' + data4.user);
    }).trigger('click', ['123', 'abc', ['a', 'b' , 'c'], {user : 'xixi'}]);
});

bind额外数据传数组:刷新弹出:123|abc|b|xixi|xixi

$(function () { 
    $('input').bind('click', {user : 'xixi'} ,function (e, data1, data2, data3, data4) {
        alert(data1 + '|' + data2 + '|' + data3[1] + '|' + data4.user + '|' + e.data.user);  
    }).trigger('click', ['123', 'abc', ['a', 'b' , 'c'], {user : 'xixi'}]);    
});

除了通过JavaScript事件名触发,也可以通过自定义的事件触发,所谓自定义事件其实就是一个被.bind()绑定的任意函数。

$(function () { 
    //click,mouseover这些系统事件,自定义事件就是自己起名字的事件
    $('input').bind('myEvent', function () {
        alert('自定义事件!');
    }).trigger('myEvent');              //执行这个自定义事件(相当于调了一个函数)
});

.trigger()方法提供了简写方案,只要想让某个事件执行模拟用户行为,直接再调用一个空的同名事件即可。

$(function () { 
    $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).click();                         //空的click()执行的是trigger()
});

jQuery还提供了另外一个模拟用户行为的方法:.triggerHandler();这个方法的使用和.trigger()方法一样。

$(function () { 
    $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).triggerHandler('click');
});

在常规的使用情况下,两者几乎没有区别,都是模拟用户行为,也可以可以传递额外参数。但在某些特殊情况下,就产生了差异:
区别一:.triggerHandler()方法并不会触发事件的默认行为,而.trigger()会

<body>
<form action="xixi.com">
    <input type="submit" value="按钮" />
</form>
</body>
$(function () { 
    //trigger提交后跳转,没有阻止默认行为
    $('form').trigger('submit');    //模拟用户执行提交,并跳转到执行页面
});
$(function () { 
    //trigger提交后没有跳转,默认行为被阻止了
    $('form').triggerHandler('submit');
});

如果我们希望使用.trigger()来模拟用户提交,并且阻止事件的默认行为,则需要这么写:

$(function () { 
    $('form').submit(function (e) {
        e.preventDefault();       //取消默认行为
    }).trigger('submit');
});

区别二:.triggerHandler()方法只会影响第一个匹配到的元素,而.trigger()会影响所有。

<body>
<input type="button" value="按钮" />
<input type="button" value="按钮" />
<input type="button" value="按钮" />
</body>
$(function () { 
    //刷新网页.trigger()会把所有都执行一遍
    $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).trigger('click');
});
$(function () { 
   //刷新网页.triggerHandler()就执行了第一个
   $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).triggerHandler('click');
});

区别三:.triggerHandler()方法会返回当前事件执行的返回值,如果没有返回值,则返回undefined;而.trigger()则返回当前包含事件触发元素的jQuery对象(方便链式连缀调用)。

$(function () { 
   //.trigger()返回jQuery对象,可以连缀
   $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
    }).trigger('click').css('color','red');                    
});
$(function () {
   //.triggerHandler()返回return值,或undefined 
   $('input').click(function () {
        alert('我将要使用模拟用户操作来触发!');
        return 123;
    }).triggerHandler('click').css('color','red');        
});

区别四:.trigger()在创建事件的时候,会冒泡。但这种冒泡是自定义事件才能体现出来,是jQuery扩展于DOM的机制,并非DOM特性。而.triggerHandler()不会冒泡。

<body>
<div class="d1">
    <div class="d2">
        <div class="d3">
            div
        </div>
    </div>
</div>
</body>
$(function () { 
   //.trigger()会冒泡
   $('div').bind('myEvent', function () {
        alert('自定义事件!');
    })
    $('.d3').trigger('myEvent');                   //让d3执行自定义事件,会冒泡
});
$(function () { 
   //.triggerHandler()不会冒泡
   $('div').bind('myEvent', function () {
        alert('自定义事件!');
    })
    $('.d3').triggerHandler('myEvent');                //让d3执行自定义事件,不会冒泡
});

二.命名空间
有时,我们想对事件进行移除。但对于同名同元素绑定的事件移除往往比较麻烦,这个时候,可以使用事件的命名空间解决。

<body>
<input type="button" value="按钮" />
</body>
$(function () { 
   $('input').bind('click.abc', function () {
        alert('abc');
    });
    
    $('input').bind('click.xixi', function () {
        alert('xixi');
    });
    $('input').bind('mouseover.abc', function () {
        alert('abc');
    });
    
    $('input').unbind('click.abc');    //移除click实践中命名空间为abc的
    $('input').unbind('.abc');         //移除实践中命名空间为.abc的
});

注意:也可以直接使用('.abc'),这样的话,可以移除相同命名空间的不同事件。对于模拟操作.trigger()和.triggerHandler(),用法也是一样的
三.事件委托
什么是事件委托?用现实中的理解就是:有100个学生同时在某天中午收到快递,但这100个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生。而在jQuery中,我们通过事件冒泡的特性,让子元素绑定的事件冒泡到父元素(或祖先元素)上,然后再进行相关处理即可。
如果一个企业级应用做报表处理,表格有2000行,每一行都有一个按钮处理。如果用之前的.bind()处理,那么就需要绑定2000个事件,就好比2000个学生同时站在学校门口等快递,不断会堵塞路口,还会发生各种意外。这种情况放到页面上也是一样,可能导致页面极度变慢或直接异常。而且,2000个按钮使用ajax分页的话,.bind()方法无法动态绑定尚未存在的元素。就好比,新转学的学生,快递员无法验证他的身份,就可能收不到快递。

<body>
<div style="width:200px;height:200px;background:green;" id="box">
    <input type="button" class="button" value="按钮" />
    <input type="button" class="button" value="按钮" />
    <input type="button" class="button" value="按钮" />
</div>
</body>

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

$(function () { 
   //.bind绑定了三个事件
    $('.button').bind('click',function () {
        alert('事件不委托!');
    });
});

使用.live()永远只会绑定一个事件

$(function () { 
    //使用live绑定的是document,而非button.所以永远只会绑定一次事件,
    $('.button').live('click',function () {
        alert('事件委托!');
    });
});

使用.bind无法动态绑定事件

$(function () { 
    $('.button').bind('click', function () {
        $(this).clone().appendTo('#box');   // 把自己克隆一份添加到box里
    });
});

使用.live()具备动态绑定功能,jQuery1.3使用,jQuery1.7之后废弃,jQuery1.9删除

$(function () { 
    //.live可以动态绑定事件,因为事件绑定在document上
    $('.button').live('click', function () {
        $(this).clone().appendTo('#box');
    });
});
//.live绑定在document上,而点击. button其实是冒泡到document上
//并且点击document时候,需要验证event.type和event.target才能触发

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

$(function () { 
    $('#box').children(0).live('click', function () {
        $(this).clone().appendTo('#box');     //报错
    });
});

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

$(function () { 
    $('.button').live('click', function () {
        $(this).clone().appendTo('#box');
    });
    //当我们需要停止事件委托的时候,可以使用.die()来取消掉。
    $('.button').die('click'); //和unbind一个意思
});

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

$(function () { 
    //.live的替代方法.delegate
    //live语义不清晰,由于他没有指定绑定了谁,所以不清晰
    //delegate语义清晰,绑定谁,谁就在开头
    $('#box').delegate('.button', 'click', function () {
        $(this).clone().appendTo('#box');
    })
    
    //$('#box').undelegate('.button','click');  //删除
});

注意:.delegate()需要指定父元素,然后第一个参数是当前元素,第二个参数是事件方式,第三个参数是执行函数。和.bind()方法一样,可以传递额外参数。.undelegate()和.unbind()方法一样可以直接删除所有事件,比如:.undelegate('click')。也可以删除命名空间的事件,比如:.undelegate('click.abc')。
注意:.live()和.delegate()和.bind()方法一样都是事件绑定,那么区别也很明显,用途上遵循两个规则:1.在 DOM 中很多元素绑定相同事件时;2.在 DOM 中尚不存在即将生成的元素绑定事件时;我们推荐使用事件委托的绑定方式,否则推荐使用.bind()的普通绑定。
四.on、off和one
目前绑定事件和解绑的方法有三组共六个。由于这三组的共存可能会造成一定的混乱,为此jQuery1.7以后推出了.on()和.off()方法彻底摒弃前面三组。
普通绑定.bind
普通解绑.unbind
事件委托.live .delegate
解除委托.die .undelegate
新方法绑定.on
新方法解绑.off
1.新方法绑定.on替代普通绑定.bind

<body>
<div style="width:200px;height:200px;background:green;" id="box">
    <input type="button" class="button" value="按钮" />
</div>
</body>

(1)替代.bind()方式

$(function () { 
    //普通绑定.bind
    $('.button').on('click', function () {
        alert('替代bind');
    });
});

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

$(function () { 
    //普通绑定.bind
    $('.button').on('click', {user : 'xixi'}, function (e) {
        alert('替代bind' + e.data.user);
    });
});

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

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

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

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

~~~~

<body>
<form action="xixi.html">
<div style="width:200px;height:200px;background:green;" id="box">
    <input type="sumbit" class="button" value="按钮" />
</div>
</form>
</body>

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

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

(6)替代.bind()方式,单一阻止默认行为或者单一取消冒泡可以用这个简便方法

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

2.新方法绑定.on替代普通解绑.unbind

<body>
<div style="width:200px;height:200px;background:green;" id="box">
    <input type="button" class="button" value="按钮" />
</div>
</body>

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

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

3.新方法绑定.on替代事件委托.live .delegate

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

4.新方法解绑.off替代解除委托.die .undelegate

$(function () { 
    $('#box').on('click','.button',function () {
        $(this).clone().appendTo('#box');
    });
    //移出事件委托
    $('#box').off('click', '.button');
});

注意:和之前方式一样,事件委托和取消事件委托也有各种搭配方式,比如额外数据、命名空间等等
不管是.bind()还是.on(),绑定事件后都不是自动移除事件的,需要通过.unbind()和.off()来手工移除。jQuery 提供了.one()方法,绑定元素执行完毕后自动移除事件,可以方法仅触发一次的事件。

$(function () { 
    //类似于.bind()只触发一次
    $('.button').one('click', function () {
        alert('仅一次事件触发!');
    });
});
$(function () { 
    //类似于.delegate()只触发一次
    $('#box').one('click', '.button', function () {
        $(this).clone().appendTo('#box');
    });
});

 

posted on 2018-03-31 17:17  我不是西西  阅读(210)  评论(0编辑  收藏  举报