2

这可能是重复的,但是,在 JavaScript 世界中,随着新浏览器的出现,情况正在迅速变化。我正在使用一些很久以前在 AS3 中使用的资源,现在它终于在 JavaScript 中流行起来了。但是,我仍然无法在课堂上进行活动。我使用 Mozilla MDN 作为指南做了这个简单的例子:

var endEvent = new Event("end");

function MyClass(text){
    this.text = text;
    this.show = function(){
        console.log("MyText: "+this.text);
        this.dispatchEvent(endEvent);
    }
}

function End(evt){
    console.log("Event dispatched: "+evt);
}

function run(){
    var MyInstance = new MyClass("I have something to say...");
    MyInstance.addEventListener("end", End, false);
    MyInstance.show();
}

在第一行,Safari 返回:“TypeError: '[object EventConstructor]' is not a constructor (evalating 'new Event("end")')”。

意思是不行?有没有办法在纯 JavaScript 中创建和调度自定义事件(不使用 jQuery 或类似的东西)?

4

2 回答 2

3

不久前我也有同样的问题

这是我想出的解决方案

需要ecmascript>= 5


function Emitter() {
  var eventTarget = document.createDocumentFragment();

  function delegate (method) {
    this[method] = eventTarget[method].bind(eventTarget);
  }

  [
    "addEventListener",
    "dispatchEvent",
    "removeEventListener"
  ].forEach(delegate, this);
}

现在是一个使用它的“类”

function Example() {
  Emitter.call(this);
}

让我们现在试试吧!

var e = new Example();

e.addEventListener("something", function(event) {
  alert("something happened! check the console too!");
  console.log(event);
});

e.dispatchEvent(new Event("something"));

凉爽的!


现在让我们看看它与您的代码一起工作。这是一个演示

// include function Emitter from above

function MyClass(text){

  Emitter.call(this);

  function show() {
    console.log("MyText:", text);
    this.dispatchEvent(new Event("end"));
  }

  this.show = show;
}

function onEnd(event){
  console.log("Event dispatched:", event);
}

function run(){
  var myInstance = new MyClass("I have something to say...");
  myInstance.addEventListener("end", onEnd, false);
  myInstance.show();
}

run();

输出

MyText: I have something to say... 
Event dispatched: Event {
  bubbles: false
  cancelBubble: false
  cancelable: false
  clipboardData: undefined
  currentTarget: null
  defaultPrevented: false
  eventPhase: 0
  path: NodeList[0]
  returnValue: true
  srcElement: null
  target: null
  timeStamp: 1406332794168
  type: "end"
  __proto__: Event
}

最后,这是一个Emitter与 ecmascript 兼容的版本< 5

// IE < 9 compatible
function Emitter() {
  var eventTarget = document.createDocumentFragment();

  function addEventListener(type, listener, useCapture, wantsUntrusted) {
    return eventTarget.addEventListener(type, listener, useCapture, wantsUntrusted);
  }

  function dispatchEvent(event) {
    return eventTarget.dispatchEvent(event);
  }

  function removeEventListener(type, listener, useCapture) {
    return eventTarget.removeEventListener(type, listener, useCapture);
  }

  this.addEventListener = addEventListener;
  this.dispatchEvent = dispatchEvent;
  this.removeEventListener = removeEventListener;
}

请参阅document.createEvent以了解旧版浏览器中的触发事件

你可以像这样制作一个polyfill(未经测试)

if (typeof Event !== "function") {
  function Event(type) {
    var e = document.createEvent("Event");
    e.initEvent(type, true, true);
    return e;
  }
}
于 2014-07-25T23:42:09.373 回答
1

在这里为我自己的教堂布道,但我最近碰巧在这方面工作,并编写了一个处理事件和继承的小型 javascript。

如果您想查看一些示例,这一切都在 github 上:

http://nicolasbize.com/moojs

(包含可点击的链接)

于 2014-07-26T00:12:49.983 回答