🚀 个人主页 极客小俊
✍🏻 作者简介:程序猿、设计师、技术分享
🐋 希望大家多多支持, 我们一起学习和进步!
🏅 欢迎评论 ❤️点赞💬评论 📂收藏 📂加关注
传统JavaScript操作事件与事件对象
在看jQuery操作事件之前,我们先回忆一下,我们使用传统的JS
操作事件是个怎么样的状态
先来看下面一个例子:
我们最常使用为元素添加onclick元素属性的方式添加事件.
为testDiv2的添加onclick事件的方式是修改Dom属性.
在上一章中已经说明了什么是元素属性, 什么是Dom属性.这两种方式的效果相同. 当单击div时会显示提示框.
请注意, 虽然效果相同, 但是并不等效.
document.getElementById("testDiv2").onclick = showMsg;
等效于:
<div id="testDiv1" onclick="alert("!!!");">单击事件 1</div>
注意两者的区别了吗? 我们常用的修改元素属性添加事件的方式, 实际上是建立了一个匿名函数:
document.getElementById("testDiv1").onclick = function(event)
{
alert("!!!");
};
这个匿名函数的签名和我们手写的showMsg签名相同, 所以可以把showMsg直接赋值给onclick.
这种方式的弊端是:
- 只能为一个事件绑定一个事件处理函数. 使用“=”赋值会把前面为此事件绑定的所有事件处理函数冲掉.
- 在事件函数(无论是匿名函数还是绑定的函数)中获取事件对象的方式在不同浏览器中要特殊处理:
IE中,事件对象是window 对象的一个属性.事件处理函数必须这样访问事件对象:
obj.onclick=function() {
var oEvent = window.event;
}
在DOM标准中,事件对象必须作为唯一参数传给事件处理函数:
obj.onclick=function() {
var oEvent = arguments[0];
}
除了使用argument[0]访问此参数, 我们也可以指定参数名称,上面的代码等同于:
obj.onclick=function(oEvent) { }
目前兼容DOM的浏览器有 Firefox,Safari,Opera,IE7等
- 添加多播委托的函数在不同浏览器中是不一样的.
所以我们首先应该摒弃<div onclick="..."></div>
这种通过修改元素属性添加事件的方式. 尽量使用添加多播事件委托的方式为一个事件绑定多个事件处理函数
比如为document对象的单击事件添加一个关闭弹出层的方法, 使用多播就不会影响document对象原有的事件处理函数.
jQuery 中的使用事件
有了jQuery, 我们有了处理对象事件的一系列函数. 上面基础知识还是要懂, 但是再也不用自己去实现处理多播事件委托的函数了. 正所谓有了jQuery, 天天喝茶水. 下面是在jQuery 中最常使用的bind()
方法举例:
$("#testDiv4").bind("click", showMsg);
举个栗子
我们为id是testDiv4的元素, 添加列click事件的事件处理函数showMsg.
使用 jQuery事件处理函数的好处:
1. 添加的是多播事件委托.
也就是为 click 事件又添加了一个方法, 不会覆盖对象的 click 事件原有的
事件处理函数.
$("#testDiv4").bind("click", function(event) { alert("one"); });
$("#testDiv4").bind("click", function(event) { alert("two"); });
单击testDiv4对象时, 依次提示"one"和"two".
2. 统一了事件名称
添加多播事件委托时, ie中是事件名称前面有"on". 但是使用bind()函数我们不用区分ie和dom , 因为内部jQuery已经帮我们统一了事件的名称.
3. 可以将对象行为全部用脚本控制
让HTML代码部分只注意"显示"逻辑. 现在的趋势是将HTML的行为, 内容与样式切分干净. 其中用脚本
控制元素行为, 用HTML标签控制元素内容, 用CSS控制元素样式. 使用jQuery事件处理函数可以避免在HTML标签上直接添加事件.
下面是基础的jQuery事件处理函数:
名称 | 说明 | 举例 |
---|---|---|
bind( type, [data], fn ) | 为每一个匹配元素的特定事件(像click) 绑定一个事件处理器函数。 | 当每个段落被点击的时候,弹出其文本: $(“p”).bind(“click”, function(){ alert( $(this).text() ); }); |
one( type, [data], fn ) | 为每一个匹配元素的特定事件(像click) 绑定一个一次性的事件处理函数。 | 当所有段落被第一次点击的时候,显示所有其文本: $(“p”).one(“click”, function(){ alert( $(this).text() ); }); |
名称 | 说明 | 举例 |
---|---|---|
trigger( event, [data] ) | 在每一个匹配的元素上触发某类事件。 这个函数也会导致浏览器同名的默认行为 的执行。比如,如果用trigger()触发一个 ‘submit’,则同样会导致浏览器提交表单。 如果要阻止这种默认行为,应返回false。 你也可以触发由bind()注册的自定义事件 | 给一个事件传递参数: $(“p”).click( function (event, a, b) { // 一个普通的点击事件时,a和 b是undefined类型 // 如果用下面的语句触发,那么a指向"foo",而b指向"bar" } ).trigger(“click”, [“foo”, “bar”]); |
triggerHandler( event, [data] ) | 这个特别的方法将会触发指定的事件类型 上所有绑定的处理函数。但不会执行浏览 器默认动作. | |
unbind( type, fn ) | bind()的反向操作,从每一个匹配的元素 中删除绑定的事件。 如果没有参数,则删除所有绑定的事件。 你可以将你用bind()注册的自定义事件取 消绑定。 如果提供了事件类型作为参数,则只删除该 类型的绑定事件。 如果把在绑定时传递的处理函数作为第二 个参数,则只有这个特定的事件处理函数会 被删除。 |
jQuery常用事件函数举例
1.bind( type, [data], fn ) 函数举例
bind()是最常使用的函数, 注意方法签名上data参数, 可以在事件处理之前传递一些附加的数据:
function handler(event) {
alert(event.data.foo);
}
$("p").bind("click", {foo: "bar"}, handler)
注意
event参数的使用. jQuery中统一了事件对象, 将事件对象作为事件处理函数的唯一参数传递.
data参数我们也要通过event.data 进行访问. 为何要提供data参数呢?
因为我们经常碰到这样的问题: 希望在事件处理中根据事件源的某些数据进行特殊处理.
目前网上有两种存在争议的解决方法:
(1) 使用自定义元素属性存储数据
.
比如:
<div id="testDiv5" customer="customer data 1">获取自定义数据‐1</div>
在事件处理函数中获取数据:
$("#testDiv5").bind("click", function(event) {
alert($(event.target).attr("customer"));
});
(2) 使用脚本将数据传递给事件处理函数
:
<div id="testDiv6">获取自定义数据‐2</div>
元素没有任何的自定义属性, 添加事件处理函数时将额外的数据传递:
$("#testDiv6").bind("click", { customer: "customer data 2" },
function(event) {
alert(event.data.customer)
});
方法1
: 便于存储和查找数据. 但是自定义属性通过不W3C 验证.
方法2
: 必须要自己想办法存储数据, 并且要制定规则查找指定元素的数据.
从"开发人员"的角度方法1 要更加简单直观. 但是缺点比较严重.
所以如何取舍请大家自己决定. one( type, [data], fn ) 函数和bind一样, 但是只执行一次.
- trigger( event, [data] ) 和 triggerHandler( event, [data] )
虽然为元素绑定了某些事件, 比如click, 但是有时希望在程序中触发这些事件, 这两个函数可以实现此
功能.
主要区别是trigger会出发浏览器默认的动作, 而triggerHandler不会出发.
通过下面的实例可以明确的区分这两个函数:
trigger函数出发了浏览器默认的获取焦点的行为,让input元素获得了焦点, 所以再次调用了focus事件处理函数.
triggerHandler只调用为focus事件绑定的事件处理函数, 而不引发浏览器行为, 所以最后input元素没
有获得焦点.
快捷事件 Event Helpers
虽然我们可以使用事件处理函数完成对象事件的几乎所有操作, 但是jQuery提供了对常用事件的封装.
比如单击事件对应的两个方法click()和click(fn)分别用来触发单击事件和设置单击事件.
设置单击事件:
$("#testDiv").click(function(event) { alert("test div clicked ! "); });
等效于:
$("#testDiv").bind("click", function(event) { alert("test div clicked ! "); });
触发单击事件:
$("#testDiv").click();
等效于
$("#testDiv").trigger("click");
注意这里等效的是trigger 而不是triggerHandler.
下面是jQuery的快捷方法列表:
blur( ) | blur( fn ) | change( ) | change( fn ) | click( ) | click( fn ) | dblclick**( )** |
---|---|---|---|---|---|---|
dblclick( fn ) | error( ) | error( fn ) | focus( ) | focus( fn ) | keydown( ) | keydown( fn ) |
keypress( ) | keypress( fn ) | keyup( ) | keyup( fn ) | load( fn ) | mousedown( fn ) | mouseenter( fn ) |
mouseleave( fn ) | mousemove( fn ) | mouseout( fn ) | mouseover( fn ) | mouseup( fn ) | resize( fn ) | scroll( fn ) |
select( ) | select( fn ) | submit( ) | submit( fn ) | unload( fn ) |
交互方法
除了基本的实践, jQuery提供了两个和事件相关的帮助方法:
hover( over, out ) 和 toggle( fn,fn2, fn3,fn4,… )
1. hover( over, out )
hover函数主要解决在原始javascript中mouseover和mouseout函数存在的问题, 看下面这个示例:
Outer1我们使用了mouseover和mouseout事件, 当鼠标从Outer1的红色区域移动到黄色区域时,
会发现虽然都是在outer1的内部移动,
但是却触发了mouseout事件:
很多时候我们不希望出现上图的结果, 而是希望只有鼠标在Outer1 内部移动时不触发事件, Outer2使用Hover()函数实现了这个效果:
注意这里的事件名称进入叫做"mouseenter",
离开叫做"mouseleave", 而不再使用"mouseover“和"mouseleave"事件.
有经验的开发人员会立刻想到在制作弹出菜单
时, 经常遇到这个问题: 为弹出菜单设置了
mouseout事件自动关闭, 但是鼠标在弹出菜单
内移动时常常莫名其妙触发mouseout事件让菜单关闭. hover()函数帮助我们很好的解决了这个问题.
如图
toggle( fn, fn2, fn3,fn4,... )
toggle函数可以为对象添加click事件绑定函数, 但是设置每次点击后依次的调用函数。
如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函
如果有更多函数,则再次触发,直到最后一个。
随后的每次点击都重复对这几个函数的轮番调用。 可以使用unbind(“click”)来删除。
使用 jQuery事件对象
使用事件自然少不了事件对象. 因为不同浏览器之间事件对象的获取, 以及事件对象的属性都有差异, 导致我们很难跨浏览器使用事件对象.
jQuery中统一了事件对象, 当绑定事件处理函数时, 会将jQuery格式化后的事件对象作为唯一参数传入:
$("#testDiv").bind("click", function(event) { });
关于event对象的详细说明, 可以参考jQuery官方文档: http://docs.jquery.com/Events/jQuery.Event
jQuery事件对象将不同浏览器的差异进行了合并, 比如可以在所有浏览器中通过 event.target 属性来获取事件的触发者(在IE中使用原生的事件对象, 需要访问event.srcElement).
事件对象除了拥有属性, 还拥有事件. 有一些是一定会用到的事件比如取消冒泡 stopPropagation() 等.
属性名称 | 描述 | 举例 |
---|---|---|
type | 事件类型.如果使用一个事件处理函数来处理多 个事件, 可以使用此属性获得事件类型,比如click. | $(“a”).click(function(event) { alert(event.type); }); |
target | 获取事件触发者DOM 对象 | $(“a[href=http://google.com]”).click(function(event) alert(event.target.href); }); |
data | 事件调用时传入额外参数. | $(“a”).each(function(i) { $(this).bind(‘click’, {index:i}, function(e){ alert('my index is ’ + e.data.index); }); }); |
relatedTarget | 对于鼠标事件, 标示触 发事件时离开或者进入 的DOM元素 | $(“a”).mouseout(function(event) { alert(event.relatedTarget); }); |
currentTarget | 冒泡前的当前触发事件 的DOM对象, 等同于 this. | $(“p”).click(function(event) { alert( event.currentTarget.nodeName ); }); 结果:P |
属性名称 | 描述 | 举例 |
---|---|---|
pageX/Y | 鼠标事件中, 事件相对 于页面原点的水平/垂直 坐标. | $(“a”).click(function(event) { alert("Current mouse position: " + event.pageX + ", " }); |
result | 上一个事件处理函数返 回的值 | $(“p”).click(function(event) { return “hey” }); $(“p”).click(function(event) { alert( event.result ); }); 结果:“hey” |
timeStamp | 事件发生时的时间戳. | var last; $(“p”).click(function(event) { if( last ) alert( "time since last event " + event.timeSta last = event.timeStamp; }); |
事件对象除了拥有属性, 还拥有事件. 有一些是一定会用到的事件比如取消冒泡
preventDefault**()** | 取消可能引起任何语意操作的事件**.** 比如**元素的href链接加载,** 表单提交以及click引起复选框的状态切换**.** | $(“a”).click(function(event){ event.preventDefault**();** // do something }); |
---|---|---|
isDefaultPrevente d() | 是否调用过 preventDefault() 方法 | $(“a”).click(function(event){ alert( event.isDefaultPrevented() ); event.preventDefault(); alert( event.isDefaultPrevented() ); }); |
stopPropagation() | 取消事件冒泡 | $(“p”).click(function(event){ event.stopPropagation(); // do something }); |
属性名称 | 描述 | 举例 |
---|---|---|
isPropagationSto pped() | 是否调用过 stopPropagation() 方法 | $(“p”).click(function(event){ alert( event.isPropagationStopped() ); event.stopPropagation(); alert( event.isPropagationStopped() ); }); |
stopImmediatePr opagation() | 取消执行其他的事件处理函数并取消事件冒泡. 如果同一个事件绑定了多个事件处理函数, 在其中一个事件处理函数中调用此方法后将不会继续调用其他的事件处理函数. | $(“p”).click(function(event){ event.stopImmediatePropagation(); }); $(“p”).click(function(event){ // This function won’t be executed }); |
isImmediateProp agationStopped() | 是否调用过 stopImmediatePropagation( ) 方法 | $(“p”).click(function(event){ alert( event.isImmediatePropagationStop event.stopImmediatePropagation(); alert( event.isImmediatePropagationStop }); |
"👍点赞" "✍️评论" "收藏❤️"
欢迎一起交流学习❤️❤️💛💛💚💚
好玩 好用 好看
的干货教程可以
点击下方关注❤️
微信公众号❤️
说不定有意料之外的收获哦..🤗嘿嘿嘿、嘻嘻嘻🤗!
🌽🍓🍎🍍🍉🍇