事件
我们主要讨论的是一些包括IE9在内的现代浏览器的事件处理。
1. Sending Native (DOM) Events 触发DOM事件
jQuery:
$(anchorElement).click();
Web API:
anchorElement.click();
上述代码工作在IE6
以上
2. Sending Custom Events 触发自定义事件
jQuery:
$('some-element').trigger('my-custom-event');
Web API:
var event = document.createEvent('Event');
event.initEvent('my-custom-event', true, true); //can bubble, and is cancellable
someElement.dispatchEvent(event);
createEvent
这个API
大多数浏览器都标记为过时了,更加现代的一些做法是:
var event = new CustomEvent('my-custom-event', {bubbles: true, cancelable: true});
someElement.dispatchEvent(event);
3. Listening For Events 监听事件
jQuery:
$(someElement).on('click', function() {
// TODO event handler logic
});
当然也可以这样:
$(someElement).click(function() {
// TODO event handler logic
});
Web API:
someElement.addEventListener('click', function() {
// TODO event handler logic
});
上述代码工作在IE9之上
4. Removing Event Handlers 移除事件
现在我们有一个事件,然后想要移除它:
var myEventHandler = function(event) {
// handles the event...
}
jQuery:
$('some-element').off('click', myEventHandler);
Web API:
someElement.removeEventListener('click', myEventHandler);
5. Modifying Events 修改事件
Preventing the event from bubbing further up the DOM 禁止事件冒泡
jQuery:
$(someEl).on('some-event', function(event) {
event.stopPropagation();
});
Web API:
someEl.addEventListener('some-event', function(event) {
event.stopPropagation();
});
Preventing the event from hitting any additional handlers attached to the current element 防止其它绑定在这个元素上的事件受到影响
jQuery:
$(someEl).on('some-event', function(event) {
event.stopImmediatePropagation();
});
Web API:
someEl.addEventListener('some-event', function(event) {
event.stopImmediatePropagation();
});
Preventing the event from triggering an action defined by the bowser 阻止事件触发浏览器定义的默认事件
<a href="http://fineuploader.com">Go to Fine Uploader</a>
现在我们想要执行点击事件,但是我们有并不像打开所关联的页面
jQuery:
$(someAnchor).on('click', function(event) {
event.preventDefault();
});
Web API:
someAnchor.addEventListener('click', function(event) {
event.preventDefault();
});
6. Event Delegation 事件代理
现在你有如下HTML
元素,你想绑定事件在每一个<li>
上,你会发现这是相当低效的。
<ul id="my-list">
<li>foo <button>x</button></li>
<li>bar <button>x</button></li>
<li>abc <button>x</button></li>
<li>123 <button>x</button></li>
</ul>
使用事件代理可以处理这种情况,当用户点击<li>
的时候,事件会冒泡到父元素上,在这个时候你可以处理这个事件:
jQuery:
$('#my-list').on('click', 'BUTTON', function() {
$(this).parent().remove();
});
Web API:
document.getElementById('my-list').addEventListener('click', function(event) {
var clickedEl = event.target;
if(clickedEl.tagName === 'BUTTON') {
var listItem = clickedEl.parentNode;
listItem.parentNode.removeChild(listItem);
}
});
7. Keyboard Events 键盘事件
Ctrl-H
键盘:
jQuery:
$(document).keydown(function(event) {
if (event.ctrlKey && event.which === 72) {
// open help widget
}
});
Web API:
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.which === 72) {
// open help widget
}
});
8. Mouse Events 鼠标事件
jQuery's hover event jQuery的hover事件
jQuery:
$('some-element').hover(
function hoverIn() {
// mouse is hovering over this element
},
function hoverOut() {
// mouse was hovering over this element, but no longer is
}
);
Web API:
someEl.addEventListener('mouseover', function() {
// mouse is hovering over this element
});
someEl.addEventListener('mouseout', function() {
// mouse was hovering over this element, but no longer is
});
9. Browser Load Events 浏览器加载完成事件
什么时候页面上的所有元素都位于正确的位置同时也完成了页面渲染?
- 所有
markup
都被放在了页面上 - 所有样式表都加载了
- 所有图片都加载了
- 所有
iframes
都被加载了
jQuery:
$(window).load(function() {
// page is fully rendered
})
Web API:
window.addEventListener('load', function() {
// page is fully rendered
});
When has all static markup been placed on the page? 什么时候页面上所有的markup
都出现在了页面上?
jQuery:
$(document).ready(function() {
// markup is on the page
});
$(function() {
// markup is on the page
});
Web API:
document.addEventListener('DOMContentLoaded', function() {
// markup is on the page
});
When has a particular element on the page fully loaded? 什么时候一个指定的元素被加载?
$('img').load(function() {
// image has successfully loaded
});
$('img').error(function() {
// image has failed to load
});
Web API:
img.addEventListener('load', function() {
// image has successfully loaded
});
img.addEventListener('error', function() {
// image has failed to load
});
10. Ancient Browser Support 对旧版本的浏览器的支持
IE7和IE8的事件添加:
someElement.attachEvent('onclick', function() {
// TODO event handler logic
});
请注意两个地方:
- 我们必须使用
attachEvent
- 事件名字必须包括一个前缀"on"
你可以使用下面代码片段来来兼容旧版本的浏览器:
function registerHandler(target, type, callback) {
var listenerMethod = target.addEventListener || target.attachEvent,
eventName = target.addEventListener ? type : 'on' + type;
listenerMethod(eventName, callback);
}
// example use
registerHandler(someElement, 'click', function() {
// TODO event handler logic
});
还有一件事情,如果你想要在IE8版本及其以下的浏览器上移除事件,你必须使用下面的代码:
function unregisterHandler(target, type, callback) {
var removeMethod = target.removeEventListener || target.detachEvent,
eventName = target.removeEventListener ? type : 'on' + type;
removeMethod(eventName, callback);
}
// example use
unregisterHandler(someElement, 'click', someEventHandlerFunction);
Form Field Change Events 表单字段改变事件
旧版本的IE有两个严重的change-event不足:
- 改变事件不会冒泡
- Checkboxes以及radio buttons完全不会触发change event
对于改变事件不会冒泡这种issue,仅仅使用事件代理是不够的,你必须还要在表单的字段上直接绑定一个change event。对于第二个issue,你可以绑定一个click事件而非change事件在radio/checkbox元素上
The Event Object 事件对象
IE8包括以下在Event
对象中是没有target
的,取而代之的是srcElement
function myEventHandler(event) {
var target = event.target || event.srcElement
// handle event & target
}
IE8阻止事件冒泡:
function myEventHandler(event) {
if (event.stopPropgation) {
event.stopPropagation();
}
else {
event.cancelBubble = true;
}
}
IE8包括以下版本的浏览器也没有stopImmediatePropagation
方法
Browser Load Events 浏览器加载事件
IE8包括以下版本也没有DOMContentLoaded
事件,IE8支持readystatechange事件,可以检测DOM是否准备好了