首页 > 网站 > WEB开发 > 正文

从零开始学习jQuery (五) 事件与事件对象

2024-04-27 14:38:22
字体:
来源:转载
供稿:网友
一.摘要

事件是脚本编程的灵魂. 所以本章内容也是jQuery学习的重点. 本文将对jQuery中的事件处理以及事件对象进行详细的讲解.

二.前言

本篇文章是至今为止本系列内容最多的一篇, 足以可见其重要性. 大家反映要多列举示例. 我会在时间允许的情况下尽量多列举示例. 真正的投入生产使用的实例暂时还无法加入到文章中, 但是可能最后我会列举一些作品供大家借鉴. 另外本人水平有限, 因为我不是UI设计师. 文章可能有错误的地方, 希望大家帮忙指出, 一起学习一起进步. 在技术的世界里我们是没有任何利益瓜葛. 希望大家都抱着彼此鼓励的心态, 对于回复中的激进评论我也都会考虑, 但是希望能够彼此尊重, 保护博客园这片程序员的净土!

三.事件与事件对象

曾经在我的 "javascript公共脚本库系列(二): 添加事件多播委托的方法" 和 "Javascript公共脚本库系列(三): 格式化事件对象/事件对象详解" 两篇文章中, 曾讲解过javascript中的事件和事件对象.

首先看一下我们经常使用的添加事件的方式:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtm
l1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>javascript中的事件</title>

<script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script>

<script type="text/javascript">
$(function()
{
document.getElementById("testDiv2").onclick = showMsg;
})

function showMsg(event)
{
alert("!!!");
}
</script>
</head>
<body>
<div id="testDiv1" onclick="showMsg();">单击事件 1</div>
<div id="testDiv2">单击事件 2</div>
</body>
</html>

3. 添加多播委托的函数在不同浏览器中是不一样的.

下面是在"Javascript公共脚本库系列(二): 添加事件多播委托的方法"文章中, 提供的兼容多浏览器添加多播委托的方法:

//统一的为对象添加多播事件委托的方法
/*
参数说明:
oTarget : 要添加事件的对象.比如"document".
sEventType : 事件类型.比如单击事件"click".
fnHandler : 发生事件时调用的方法. 比如一个静态函数"hideCalendar"

使用举例:
//单击页面的任何元素,只要没有取消冒泡,都可以关闭日历控件
var cf = document.getElementById("CalFrame");
if( cf != null && hideCalendar != null )
{
ScriptHelper.addEventListener( document, "click", hideCalendar );
}
*/
scriptHelper.prototype.addEventListener = function(oTarget, sEventType, fnHandler)
{
if( oTarget.addEventListener )//for dom
{
oTarget.addEventListener( sEventType, fnHandler, false )
}
else if( oTarget.attachEvent )//for ie
{
oTarget.attachEvent( "on" + sEventType, fnHandler);
}
}

2. 统一了事件名称.
添加多播事件委托时, ie中是事件名称前面有"on". 但是使用bind()函数我们不用区分ie和dom , 因为内部jQuery已经帮我们统一了事件的名称.

3. 可以将对象行为全部用脚本控制.
让HTML代码部分只注意"显示"逻辑. 现在的趋势是将HTML的行为, 内容与样式切分干净. 其中用脚本控制元素行为, 用HTML标签控制元素内容, 用CSS控制元素样式. 使用jQuery事件处理函数可以避免在HTML标签上直接添加事件.

下面是基础的jQuery事件处理函数:

事件处理 Event Handling:

名称 说明 举例

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] ) 这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作. 如果你对一个focus事件执行了 .triggerHandler() ,浏览器默认动作将不会被触发,只会触发你绑定的动作:

$("#old").click(function(){
$("input").trigger("focus");
});
$("#new").click(function(){
$("input").triggerHandler("focus");
});
$("input").focus(function(){ $("Focused!").appendTo("body").fadeOut(1000); });

unbind( type, fn ) bind()的反向操作,从每一个匹配的元素中删除绑定的事件。

如果没有参数,则删除所有绑定的事件。

你可以将你用bind()注册的自定义事件取消绑定。

如果提供了事件类型作为参数,则只删除该类型的绑定事件。

如果把在绑定时传递的处理函数作为第二个参数,则只有这个特定的事件处理函数会被删除。

把所有段落的所有事件取消绑定:
$("p").unbind()

将段落的click事件取消绑定:
$("p").unbind( "click" )

删除特定函数的绑定,将函数作为第二个参数传入:

var foo = function () {
// 处理某个事件的代码
};
$("p").bind("click", foo); // ... 当点击段落的时候会触发 foo
$("p").unbind("click", foo); // ... 再也不会被触发 foo

五.常用事件函数举例1.bind( type, [data], fn ) 函数举例

bind()是最常使用的函数, 注意方法签名上data参数, 可以在事件处理之前传递一些附加的数据:

function handler(event) {
alert(event.data.foo);
}
$("p").bind("click", {foo: "bar"}, handler)

(1) 使用自定义元素属性存储数据.

比如:

<div id="testDiv5" customer="customer data 1">获取自定义数据-1</div>

六.快捷事件 Event Helpers

BUG提示:jquery-1.3.2-vsdoc2.js 这个最新的官方带智能提示的类库, 无法使用快捷事件, 比如click(), focus(). 使用其他版本的类库则没有问题.

虽然我们可以使用事件处理函数完成对象事件的几乎所有操作, 但是jQuery提供了对常用事件的封装. 比如单击事件对应的两个方法click()和click(fn)分别用来触发单击事件和设置单击事件.

设置单击事件:

$("#testDiv").click(function(event) { alert("test div clicked ! "); });

很多时候我们不希望出现上图的结果, 而是希望只有鼠标在Outer1内部移动时不触发事件, Outer2使用Hover()函数实现了这个效果:

注意这里的事件名称进入叫做"mouseenter", 离开叫做"mouseleave", 而不再使用"mouSEOver"和"mouseleave"事件.

有经验的开发人员会立刻想到在制作弹出菜单时, 经常遇到这个问题: 为弹出菜单设置了mouseout事件自动关闭, 但是鼠标在弹出菜单内移动时常常莫名其妙触发mouseout事件让菜单关闭. hover()函数帮助我们很好的解决了这个问题.

2. toggle( fn, fn2, fn3,fn4,... )

toggle函数可以为对象添加click事件绑定函数, 但是设置每次点击后依次的调用函数。

如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数,如果有更多函数,则再次触发,直到最后一个。随后的每次点击都重复对这几个函数的轮番调用。

可以使用unbind("click")来删除。

下面的示例演示如何使用toggle函数:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>toggle example</title>
<link rel="stylesheet" type="text/css" href="css/hover.css">

<script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script>

<script type="text/javascript">
$(function()
{
$("li").toggle(
function()
{
$(this).css({ "list-style-type": "disc", "color": "blue" });
},
function()
{
$(this).css({ "list-style-type": "square", "color": "red" });
},
function()
{
$(this).css({ "list-style-type": "none", "color": "" });
}
);
})
</script>

</head>
<body>
<ul>
<li style="cursor:pointer">click me</li>
</ul>
</body>
</html>

上面是jQuery官方文档中提供的event对象的属性. 在"jQuery实战"一书中还提供了下面的多浏览器支持的属性, 时间关系我没有尝试每一个属性, 大家可以帮忙验证是否在所有浏览器下可用:

属性名称 描述 举例
altKey Alt键是否被按下. 按下返回true
ctrlKey ctrl键是否被按下, 按下返回true
metaKey Meta键是否被按下, 按下返回true.
meta键就是PC机器的Ctrl键,或者Mac机器上面的Command键
shiftKey Shift键是否被按下, 按下返回true
keyCode 对于keyup和keydown事件返回被按下的键. 不区分大小写, a和A都返回65.

对于keypress事件请使用which属性, 因为which属性跨浏览时依然可靠.
which 对于键盘事件, 返回触发事件的键的数字编码. 对于鼠标事件, 返回鼠标按键号(1左,2中,3右).
screenX/Y 对于鼠标事件, 获取事件相对于屏幕原点的水平/垂直坐标

事件对象除了拥有属性, 还拥有事件. 有一些是一定会用到的事件比如取消冒泡 stopPropagation() 等.下面是jQuery事件对象的函数列表:

名称 说明 举例
preventDefault() 取消可能引起任何语意操作的事件. 比如元素的href链接加载, 表单提交以及click引起复选框的状态切换.
$("a").click(function(event){ event.preventDefault(); // do something});
isDefaultPrevented() 是否调用过 preventDefault() 方法
$("a").click(function(event){ alert( event.isDefaultPrevented() ); event.preventDefault(); alert( event.isDefaultPrevented() );});
stopPropagation() 取消事件冒泡
$("p").click(function(event){ event.stopPropagation(); // do something});
isPropagationStopped() 是否调用过 stopPropagation() 方法
$("p").click(function(event){ alert( event.isPropagationStopped() ); event.stopPropagation(); alert( event.isPropagationStopped() );});
stopImmediatePropagation() 取消执行其他的事件处理函数并取消事件冒泡.

如果同一个事件绑定了多个事件处理函数, 在其中一个事件处理函数中调用此方法后将不会继续调用其他的事件处理函数.
$("p").click(function(event){ event.stopImmediatePropagation();});$("p").click(function(event){ // This function won't be executed});
isImmediatePropagationStopped() 是否调用过 stopImmediatePropagation() 方法
$("p").click(function(event){ alert( event.isImmediatePropagationStopped() ); event.stopImmediatePropagation(); alert( event.isImmediatePropagationStopped() );});

这些函数中 stopPropagation() 是我们最长用的也是一定会用到的函数. 相当于操作原始event对象的event.cancelBubble=true来取消冒泡.

九. 总结

事件是javascript的灵魂, 我花了很久写这篇文章,翻译jQuery官方的API文档. 列表中的很多例子直接从官网上摘抄的, 有些列表中的方法我也没有用过, 所以如果大家发现问题请及时通知我修改.

接下来的文章将分别讲解Ajax和动画效果. 最后通过讲解两个我修改的jQuery插件来学习jQuery的插件开发.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表