本文概述
- 听事件
- 调度自定义事件
- Polyfill
你可以使用CustomEvent API创建自己的事件, 以便像通常对现有事件那样使用事件侦听器对这些事件做出反应。
听事件当我们要使用CustomEvent API调度事件时, 我们需要先监听它, 否则我们将永远不会得到任何结果。
请记住, 事件只能在DOM元素(文档, 输入, 按钮, div等)上调度。在这种情况下, 该事件将被命名为” OurSuperEvent” , 并且将在下一步中将其调度到文档上, 因此也将为该文档添加侦听器。
var element = document;
// or // var element = document.getElementById("aRandomId");
element.addEventListener("OurSuperEvent", function (e) {// This is the information that we receive from the CustomEventconsole.log("The custom data of the event is : ", e.detail);
// The event as itself (object with properties like {srcElement, isTrusted, target, defaultPrevent etc})console.log("Event is : ", e);
}, false);
事件的detail属性包含调度事件时发送的信息。
注意:如前所述, 事件侦听器已添加到document元素。因此, 该事件也需要在document元素中调度, 否则该事件将永远不会被监听, 因为它不是我们为此事件分配的元素。
调度自定义事件现在我们有了一个侦听器, 可以告诉我们事件何时发生, 你需要学习如何调度它。
在侦听器中, 我们将侦听器附加到文档, 因此我们的事件(为了被侦听)也将在文档中调度。
var myData = http://www.srcmini.com/{id: 1, name:"An imaginary name", customProperty:"I need to know this string when the event is dispatched", moreData: [1, 2, 4, 5, 6, 7]};
var element = document;
// or // var element = document.getElementById("aRandomId");
// The custom event that receives as first parameter the name of the type of the dispatchedEventvar event = new CustomEvent("OurSuperEvent", { detail: myData });
element.dispatchEvent(event);
如你所见, 自定义事件的实现非常简单, 简约和简洁。
但是(在Java语言世界中始终如此), 某些浏览器(Internet Explorer)没有实现相同的初始化。
当浏览器中存在window.CustomEvent对象时, 不能将其称为构造函数。代替新的CustomEvent(… ), 必须使用event = document.createEvent(‘ CustomEvent’ ), 然后使用event.initCustomEvent(… ), 如以下示例所示:
var myData = http://www.srcmini.com/{id: 1, name:"An imaginary name", customProperty:"I need to know this string when the event is dispatched", moreData: [1, 2, 4, 5, 6, 7]};
var element = document;
// or // var element = document.getElementById("aRandomId");
//Dispatch an eventvar event = document.createEvent("CustomEvent");
event.initCustomEvent("OurSuperEvent", true, true, myData);
element.dispatchEvent(event);
Polyfill请注意, 某些版本的Android旧的基于WebKit的WebView不支持CustomEvent API。幸运的是, 此功能有一个polyfill。
此摘要涵盖了事件IE6。该脚本可填充addEventListener, removeEventListener, dispatchEvent, CustomEvent和DOMContentLoaded。压缩并压缩后不到一半千字节。
你可以在此处访问存储库并查看源代码, 或直接在此处获取polyfill:
// EventListener | CC0 | github.com/jonathantneal/EventListenerthis.Element &
&
Element.prototype.attachEvent &
&
!Element.prototype.addEventListener &
&
(function () { function addToPrototype(name, method) {Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = method;
} // add addToPrototype("addEventListener", function (type, listener) {vartarget = this, listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, typeListeners = listeners[type] = listeners[type] || [];
// if no events exist, attach the listenerif (!typeListeners.length) {target.attachEvent("on" + type, typeListeners.event = function (event) {var documentElement = target.document &
&
target.document.documentElement || target.documentElement || { scrollLeft: 0, scrollTop: 0 };
// polyfill w3c properties and methodsevent.currentTarget = target;
event.pageX = event.clientX + documentElement.scrollLeft;
event.pageY = event.clientY + documentElement.scrollTop;
event.preventDefault = function () { event.returnValue = http://www.srcmini.com/false };
event.relatedTarget = event.fromElement || null;
event.stopImmediatePropagation = function () { immediatePropagation = false;
event.cancelBubble = true };
event.stopPropagation = function () { event.cancelBubble = true };
event.target = event.srcElement || target;
event.timeStamp = +new Date;
var plainEvt = {};
for (var i in event) {plainEvt[i] = event[i];
}// create an cached list of the master events list (to protect this loop from breaking when an event is removed)for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true;
immediatePropagation &
&
(typeListenerCache = typeListenersCache[i]);
++i) {// check to see if the cached event still exists in the master events listfor (var ii = 0, typeListener;
typeListener = typeListeners[ii];
++ii) {if (typeListener == typeListenerCache) {typeListener.call(target, plainEvt);
break;
}}}});
}// add the event to the master event listtypeListeners.push(listener);
});
// remove addToPrototype("removeEventListener", function (type, listener) {vartarget = this, listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, typeListeners = listeners[type] = listeners[type] || [];
// remove the newest matching event from the master event listfor (var i = typeListeners.length - 1, typeListener;
typeListener = typeListeners[i];
--i) {if (typeListener == listener) {typeListeners.splice(i, 1);
break;
}}// if no events exist, detach the listenerif (!typeListeners.length &
&
typeListeners.event) {target.detachEvent("on" + type, typeListeners.event);
} });
// dispatch addToPrototype("dispatchEvent", function (eventObject) {vartarget = this, type = eventObject.type, listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, typeListeners = listeners[type] = listeners[type] || [];
try {return target.fireEvent("on" + type, eventObject);
} catch (error) {if (typeListeners.event) {typeListeners.event(eventObject);
}return;
} });
// CustomEvent Object.defineProperty(Window.prototype, "CustomEvent", {get: function () {var self = this;
return function CustomEvent(type, eventInitDict) {var event = self.document.createEventObject(), key;
event.type = type;
for (key in eventInitDict) {if (key == 'cancelable'){event.returnValue = http://www.srcmini.com/!eventInitDict.cancelable;
} else if (key =='bubbles'){event.cancelBubble = !eventInitDict.bubbles;
} else if (key == 'detail'){event.detail = eventInitDict.detail;
}}return event;
};
} });
// ready function ready(event) {if (ready.interval &
&
document.body) {ready.interval = clearInterval(ready.interval);
document.dispatchEvent(new CustomEvent("DOMContentLoaded"));
} } ready.interval = setInterval(ready, 1);
window.addEventListener("load", ready);
})();
(!this.CustomEvent || typeof this.CustomEvent === "object") &
&
(function() { // CustomEvent for browsers which don't natively support the Constructor method this.CustomEvent = function CustomEvent(type, eventInitDict) {var event;
eventInitDict = eventInitDict || {bubbles: false, cancelable: false, detail: undefined};
try {event = document.createEvent('CustomEvent');
event.initCustomEvent(type, eventInitDict.bubbles, eventInitDict.cancelable, eventInitDict.detail);
} catch (error) {// for browsers which don't support CustomEvent at all, we use a regular event insteadevent = document.createEvent('Event');
event.initEvent(type, eventInitDict.bubbles, eventInitDict.cancelable);
event.detail = eventInitDict.detail;
}return event;
};
})();
【如何在JavaScript中为DOM元素创建自定义事件】玩得开心 !
推荐阅读
- 如何使用JavaScript将文本轻松复制到剪贴板
- 混淆你的JavaScript,使用户无法阅读
- IntersectionObserver功能(Chrome 51功能,知道特定元素何时处于视口内或视口外)
- 如何覆盖JavaScript中的console方法
- “use strict”是什么(用JavaScript表示)
- 如何使用JavaScript从网络摄像头生成ascii艺术照片
- 如何使用javascript将URL(网站,电子邮件)从字符串转换为html标签
- 如何防止修改JavaScript中的对象并防止它们在控制台中访问
- 如何使用XMLHttpRequest(jQuery Ajax)绕过”Access-Control-Allow-Origin”错误