最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

addeventlistener - How to trigger JavaScript custom events correctly - Stack Overflow

programmeradmin1浏览0评论

I am struggling to understand how a custom event type is linked to a specific user action/trigger. All documentation seems to dispatch the event without any user interaction.

In the following example I want the event to be dispatched once a user has been hovering on the element for 3 seconds.

var img = document.createElement('img');img.src = '';
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);
};

I have a trigger but no logical way of connecting it to the event.

I was thinking about creating an object called CustomEventTrigger which is essentially CustomEvent but has a third parameter for the trigger and also creating a method called addCustomEventListener, which works the same as addEventListener but when initialised it then passes the target Element to the custom event trigger which then dispatches the event when it's instructed to.

I am struggling to understand how a custom event type is linked to a specific user action/trigger. All documentation seems to dispatch the event without any user interaction.

In the following example I want the event to be dispatched once a user has been hovering on the element for 3 seconds.

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);
};

I have a trigger but no logical way of connecting it to the event.

I was thinking about creating an object called CustomEventTrigger which is essentially CustomEvent but has a third parameter for the trigger and also creating a method called addCustomEventListener, which works the same as addEventListener but when initialised it then passes the target Element to the custom event trigger which then dispatches the event when it's instructed to.

Share Improve this question edited Nov 22, 2016 at 19:29 TarranJones asked Jun 25, 2015 at 10:36 TarranJonesTarranJones 4,2522 gold badges41 silver badges56 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

Custom events have to be triggered programatically through dispatchEvent, they are not fired by the DOM. You will always need to explictly call them in your code, such as in response to a user-generated event such as onmouseover, or a change of state such as onload.

You're very close to a working implementation, however you're immediately invoking dispatchEvent in your setTimeout. If you save it into a closure (as below) you can invoke dispatchEvent while passing your element after setTimeout has finished the timeout.

It's also good practice to declare your variables at the top of a file, to avoid possible scope issues.

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);

I have created a method called addCustomEventListener, which works the same as addEventListener but when initialised passes the target Element to the custom event trigger which dispatches the event when it says, so in this case it only dispatches if the timeout reaches 3 seconds.

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" ;/>

I think this could be useful to others so please feel free to improve on this.

发布评论

评论列表(0)

  1. 暂无评论