创建和触发events
创建自定义事件
以下内容部分来自于MDN
Events 可以使用 Event构造函数 创建如下:
var event = new Event('build');
// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);
// Dispatch the event.
elem.dispatchEvent(event);
绝大多数现代浏览器中都会支持这个构造函数(Internet Explorer 例外)。
添加自定义数据 – CustomEvent()
To add more data to the event object, the CustomEvent interface exists and the detail property can be used to pass custom data.
CustomEvent 接口可以为 event 对象添加更多的数据。例如,event 可以创建如下:
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
下面的代码允许你在事件监听器中访问更多的数据:
function eventHandler(e) {
log('The time is: ' + e.detail);
}
触发内置事件
下面的例子演示了一个在复选框上点击(click
)的模拟(就是说在程序里生成一个click
事件),这个模拟点击使用了DOM方法.
function simulateClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('checkbox');
var cancelled = !cb.dispatchEvent(event);
if (cancelled) {
// A handler called preventDefault.
alert("cancelled");
} else {
// None of the handlers called preventDefault.
alert("not cancelled");
}
}
动态事例
<input type="checkbox" id="checkbox"/><label for="checkbox">Checkbox</label>
<!-- Simulate click -->
<input type="button" onclick="simulateClick();" value="Simulate click"/>
<!-- Add a click handler that calls preventDefault -->
<input type="button" onclick="addHandler();" value="Add a click handler that calls preventDefault"/>
<!-- Remove the click handler that calls preventDefault -->
<input type="button" onclick="removeHandler();" value="Remove the click handler that calls preventDefault"/>
function preventDef(event) {
event.preventDefault();
}
function addHandler() {
document.getElementById("checkbox").addEventListener("click",
preventDef, false);
}
function removeHandler() {
document.getElementById("checkbox").removeEventListener("click",
preventDef, false);
}
function simulateClick() {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("checkbox");
var canceled = !cb.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
创建指定类型事件Document.createEvent()
详细信息可以参见:Document.createEvent()
创建一个指定类型的事件。其返回的对象必须先初始化并可以被传递给 element.dispatchEvent
。
语法
var event = document.createEvent(type);
- event 就是被创建的 Event 对象.
- type 是一个字符串,表示要创建的事件类型。事件类型可能包括”
UIEvents
“, “MouseEvents
“, “MutationEvents
“, 或者 “HTMLEvents
“。
示例
// Create the event.
var event = document.createEvent('Event');
// Define that the event name is 'build'.
event.initEvent('build', true, true);
// Listen for the event.
elem.addEventListener('build', function (e) {
// e.target matches elem
}, false);
// target can be any Element or other EventTarget.
elem.dispatchEvent(event);
采用自定义事件监听某个变量的变化
以下内容原文地址: javascript自定义事件(event)
标准浏览器(firefox,chrome,safari,opera等)的实现非常简单,自然,有一个document.createEvent()
的函数来专门创建自定义事件,使用起来也很简单。
var event = document.createEvent(type);
简单的说来,自定义事件到激发这个事件,需要document.createEvent()
,event.initEvent()
,element.dispatchEvent()
这三步,分别是创建事件对象,初始化事件对象,触发事件。先给个简单的例子。
function foo1(){
console.log("foo1 is execute");
}
function foo2(){
console.log("foo2 is execute");
}
var ev=document.createEvent('HTMLEvents');
ev.initEvent('fakeEvent',false,false);
document.addEventListener("fakeEvent",foo1,false);
document.addEventListener("fakeEvent",foo2,false);
在标准浏览器里的console里执行 document.dispatchEvent(ev)
; 就可以看到console里显示出来了 foo1 is execute和 foo2 is execute
自定义事件已经实现了,那么怎么实现监听某个变量的变化呢?我们可以使用一个特定的函数来给变量赋值,在这个函数中,除了执行给变量赋值的操作外,还激发事件。为了约束程序员直接对变量复制,使用下面的代码来强制程序员不能直接对该变量赋值。
var idChange=function(){
var id=1;
return {
getId:function(){return id;},
setId:function(a){
id=a;
document.dispatchEvent(ev);
}}
}();
这样就只能通过idChange.setId()
的方法对id赋值,通过 idChange.getId()
来获得id的值,并且在赋值的过程中激发事件。
在标准浏览器里,现在已经实现了目标,遗憾的是IE并不支持document.createEvent()的方法,在JavaScript权威指南第五版中,作者给出IE支持的 document.createEventObject()和event.fireEvent()方法,但是经过测试,fireEvent并不能用于自定义事件,传给它的参数只能是在IE已经定义了的事件。在Dean Edwards的博客中看到了一个方法,这里就直接拿来用了,性能方面值得考虑,请阅读这篇博客下面的评论部分,就会知道怎么改进这个方法的性能,为了方便,我这里直接用他博客中给的方法了,为了更直观,也添加了一个addLog()函数,来直接在页面中记录事件的发生, 为了配合addLog函数,页面中要有一个id为 log 的div ,具体代码如下:
function foo1(){
addLog("foo1 is excute");
}
function foo2(){
addLog("the id is "+idChange.getId()+" now!");
}
if(document.createEvent){ //This is for the stand browser.
var ev=document.createEvent('HTMLEvents');
ev.initEvent('fakeEvent',false,false);
document.addEventListener("fakeEvent",foo1,false);
document.addEventListener("fakeEvent",foo2,false);
}else if(document.attachEvent){ //This is for the damn IE
document.documentElement.fakeEvents = 0; // an expando property
document.documentElement.attachEvent("onpropertychange", function(event) {
if (event.propertyName == "fakeEvents") {
foo1();
}
});
document.documentElement.attachEvent("onpropertychange",function(event){
if(event.propertyName == "fakeEvents"){
foo2();
}
});
}
function addLog(log){
var logDiv=document.getElementById('log');
var p=document.createElement("p");
p.appendChild(document.createTextNode(log));
logDiv.appendChild(p);
}
var idChange=function(){
var id=1;
return {
getId:function(){return id;},
setId:function(a){
id=a;
if(document.dispatchEvent) document.dispatchEvent(ev);
else if(document.attachEvent) document.documentElement.fakeEvents++; //This for IE
}
}
}();
现在我们就已经实现了文章开头想要达到的需求,在浏览器地址栏里执行javascript:idChange.setId(8)
就可以看见效果了。监听某个变量的变化了,你可能会想到,干嘛不直接在idChange.setId()
中直接执行 foo1()
,foo2()
,是的,这样也可以实现,但是这样不是真正的事件,如果你在代码中多处需要注册监听器到这个自定义事件,并且随时需要取消注册,显然这种事件的方法更容易管理一些,另外事件还有另外的好处,代码更稳定。
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=2267