繁体   English   中英

如何正确触发 JavaScript 自定义事件

[英]How to trigger JavaScript custom events correctly

我正在努力理解自定义事件类型如何链接到特定的用户操作/触发器。 所有文档似乎都在没有任何用户交互的情况下调度事件。

在以下示例中,我希望在用户将鼠标悬停在元素上 3 秒后调度该事件。

var img = document.createElement('img');img.src = 'http://placehold.it/100x100';
document.body.appendChild(img)
var event = new CustomEvent("hoveredforthreeseconds");

img.addEventListener('hoveredforthreeseconds', function(e) { console.log(e.type)}, true);


var thetrigger = function (element, event) {
    var timeout = null;
    element.addEventListener('mouseover',function() {
        timeout = setTimeout(element.dispatchEvent(event), 3000);
    },true);
    element.addEventListener('mouseout', function() {
        clearTimeout(timeout);
    },true);
};

我有一个触发器,但没有将它连接到事件的逻辑方式。

我正在考虑创建一个名为CustomEventTrigger的对象,它本质上是CustomEvent但具有触发器的第三个参数,并且还创建了一个名为addCustomEventListener的方法,它的工作方式与addEventListener相同,但在初始化时,它将目标元素传递给自定义事件触发器然后在收到指示时分派该事件。

自定义事件必须通过dispatchEvent以编程方式触发,它们不会被 DOM 触发。 您将始终需要在代码中显式调用它们,例如响应用户生成的事件(例如onmouseover )或状态更改(例如onload

您非常接近工作实现,但是您立即在setTimeout调用dispatchEvent 如果将其保存到闭包中(如下所示),则可以在setTimeout完成超时后传递元素时调用dispatchEvent

在文件顶部声明变量也是一种很好的做法,以避免可能的范围问题。

var img = document.createElement('img'), timeout, event, thetrigger;

img.src = 'http://placehold.it/100x100';
document.body.appendChild(img);

img.addEventListener("hoveredForThreeSeconds", afterHover, false);

thetrigger = function (element, event) {
    timeout = null;
    element.addEventListener('mouseover',function() {
      timeout = setTimeout(function(){ element.dispatchEvent(event) }, 3000);
    },true);
    element.addEventListener('mouseout', function() {
        clearTimeout(timeout);
    },true);
};

function afterHover(e) {
    console.log("Event is called: " + e.type);
}

event = new CustomEvent("hoveredForThreeSeconds");

thetrigger(img, event);

我创建了一个名为addCustomEventListener的方法,它的工作方式与addEventListener相同,但是在初始化时将目标元素传递给自定义事件触发器,该触发器在它说时调度事件,因此在这种情况下,它仅在超时达到 3 秒时调度。

 var img = document.getElementById('img'); window.mouseover3000 = new CustomEvent('mouseover3000', { detail: { trigger: function(element, type) { timeout = null; element.addEventListener('mouseover', function() { timeout = setTimeout(function() { element.dispatchEvent(window[type]) }, 3000); }, false); element.addEventListener('mouseout', function() { clearTimeout(timeout); }, false) } } }); window.tripleclick = new CustomEvent('tripleclick', { detail: { trigger: function(element, type) { element.addEventListener('click', function(e) { if(e.detail ===3){ element.dispatchEvent(window[type]) } }, false); } } }); EventTarget.prototype.addCustomEventListener = function(type, listener, useCapture, wantsUntrusted) { this.addEventListener(type, listener, useCapture, wantsUntrusted); window[type].detail.trigger(this, type); } var eventTypeImage = function(e) { this.src = "http://placehold.it/200x200?text=" + e.type; } img.addEventListener('mouseout', eventTypeImage, false); img.addEventListener('mouseover', eventTypeImage, false); img.addCustomEventListener('mouseover3000', eventTypeImage, false); img.addCustomEventListener('tripleclick', eventTypeImage, false);
 <img id="img" src="http://placehold.it/200x200?text=No+hover" ;/>

我认为这可能对其他人有用,因此请随时对此进行改进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM