“事件是把所有东西粘在一起的胶水”,没有事件就没有JavaScript强大的交互作用。
基本认识
1.JavaScript是完全异步的。这就意味着你不必去处理那些烦人的多线程问题,可以轻松监听及响应各种事件。
2.对于事件的处理我们只需要使用事件处理函数简单地注册一个回调函数,当事件触发时,回调函数将会被调用执行。
function loaded() {
alert( ' Finished! ' );
}
// 注册回调函数
window.onload = loaded;
3.事件的两个阶段:捕获和冒泡。或许你和我一样,在相当长时间内并没有注意到这两个概念。
以下是一段简单的HTML模型:
<
body
>
<
div
>
<
ul
>
<
li
>
点击此处
</
li
>
</
ul
>
</
div
>
</
body
>
现在我们看看浏览器是怎样“捕获”和“冒泡”的。
假如我们在li中发生了点击(clikc)事件,body元素会首先“捕获”到事件,如果我们为点击事件设置了事件处理函数,这时候会执行事件处理函数。接着依次是div、ul、li,“捕获”并响应事件。这时事件从“捕获”阶段进入了“冒泡”阶段,li、ul、div、body依次又执行了他们相应的事件处理函数。实际上,你可以为“捕获”和“冒泡”阶段分别绑定不同的函数。
这时候你不要急着用onclick = function(){...}这种方法去尝试这样的机制,因为它只支持冒泡机制而忽略了捕获过程。更为重要的是,不管你用什么方式去注册一个事件处理程序,IE只工作在冒泡阶段,也就是说IE并不支持捕获机制。
=========================================================================
在写接下来的内容之前先F一下微软这个混蛋成天搞特殊,IE的事件对象的实现和W3C标准是不一样的,所以我们总是要在我们的函数中处理这样的差异。以下代码可以消除这样的一种差异:
//
e为函数参数中传入的事件对象
e
=
e
||
window.event;
废话少说,马上进入正题!(以下代码绝大部分来自于《精通JavaScript》)
阻止事件冒泡
刚才跟大家看到了JavaScript冒泡的机制,但在某些情况下,你可能不想让事件响应出现这样的情况。我们有办法阻止这样的情况发生。
以下是一段阻止冒泡的通用代码
// 如果传入了事件对象,那么就是非IE浏览器
if (e && e.stopPropagation)
// 支持W3C的stopPropation()方法
e.stopPropagation();
else
// 否则,我们得使用IE的方式来取消事件冒泡
window.event.cancelBubble = true ;
}
应用举例
<
div id
=
"
divTag
"
>
<
ul id
=
"
ulTag
"
>
<
li id
=
"
liTag
"
>
点击此处
<
/
li>
<
/
ul>
<
/
div>
<
script type
=
"
text/javascript
"
>

//
分别获取三个元素
l
=
document.getElementById(
'
liTag
'
);
u
=
document.getElementById(
'
ulTag
'
);
d
=
document.getElementById(
'
divTag
'
);
//
为三个元素注册点击响应函数

l.onclick
=
function
(e)
{
alert('li tag');
}

u.onclick
=
function
(e)
{
alert('ul tag');
//阻止冒泡
stopBubble(e);
}

d.onclick
=
function
(e)
{
alert('div tag');
}
<
/
script>
从这个例子中可以看到冒泡以及冒泡被阻止的情况。
阻止默认行为
很多事件具有默认行为,比如点击submit按钮时会提交表单数据及页面转向。
阻止冒泡并不能阻止默认行为,因此我们还需要写一个阻止默认行为的函数,并且是通用函数(你可以猜到IE又一次背离了标准)
if (e && e.preventDefault)
e.preventDefault();
else
window.event.returnValue = false ;
return false ;
}
Dean Edward 的 addEvent 和 removeEvent 函数
// addEvent/removeEvent written by Dean Edwards, 2005
// with input from Tino Zijdel
// http://dean.edwards.name/weblog/2005/10/add-event/

function addEvent(element, type, handler)
{
// assign each event handler a unique ID
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
// create a hash table of event types for the element
if (!element.events) element.events =
{};
// create a hash table of event handlers for each element/event pair
var handlers = element.events[type];
if (!handlers)
{
handlers = element.events[type] =
{};
// store the existing event handler (if there is one)
if (element["on" + type])
{
handlers[0] = element["on" + type];
}
}
// store the event handler in the hash table
handlers[handler.$$guid] = handler;
// assign a global event handler to do all the work
element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler)
{
// delete the event handler from the hash table
if (element.events && element.events[type])
{
delete element.events[type][handler.$$guid];
}
};

function handleEvent(event)
{
var returnValue = true;
// grab the event object (IE uses a global event object)
event = event || fixEvent(window.event);
// get a reference to the hash table of event handlers
var handlers = this.events[event.type];
// execute each event handler
for (var i in handlers)
{
this.$$handleEvent = handlers[i];
if (this.$$handleEvent(event) === false)
{
returnValue = false;
}
}
return returnValue;
};

function fixEvent(event)
{
// add W3C standard event methods
event.preventDefault = fixEvent.preventDefault;
event.stopPropagation = fixEvent.stopPropagation;
return event;
};
fixEvent.preventDefault = function()
{
this.returnValue = false;
};
fixEvent.stopPropagation = function()
{
this.cancelBubble = true;
};
Dean Edward的addEvent函数对各个浏览器的支持都很好,因为他采用的是绑定事件处理函数的传统手段;this关键字可以在所有绑定函数中使用,指向的是当前元素;中和了所有防止浏览器默认行为和阻止事件冒泡的各种浏览器特定参数。
另外,由于IE缺乏对捕获过程的支持,addEvent仅工作在冒泡阶段。
本文深入探讨JavaScript事件处理机制,包括事件的捕获与冒泡、如何阻止事件冒泡及默认行为等核心概念。同时介绍了Dean Edwards的addEvent和removeEvent函数,帮助开发者更好地管理事件。

2万+

被折叠的 条评论
为什么被折叠?



