2

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

在下面的示例中,我希望在用户将鼠标悬停在元素上 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并且还创建一个名为当它被指示时。addCustomEventListeneraddEventListener

4

2 回答 2

1

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

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

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

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);
于 2015-06-25T11:36:50.000 回答
1

我创建了一个名为 的方法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" ;/>

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

于 2015-06-25T13:22:59.823 回答