创建和触发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(),是的,这样也可以实现,但是这样不是真正的事件,如果你在代码中多处需要注册监听器到这个自定义事件,并且随时需要取消注册,显然这种事件的方法更容易管理一些,另外事件还有另外的好处,代码更稳定。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注