setTimeout干扰加载事件处理程序

时间:2016-10-15 00:07:31

标签: javascript javascript-events settimeout race-condition

我在load元素上附加<track>事件处理程序。即使在<track>已经加载后附加了处理程序,我怎样才能确保处理程序被调用?

E.g。

track.addEventListener('load', function () {
    //this should get called even if the track has already loaded
});

4 个答案:

答案 0 :(得分:1)

如果在没有附加侦听器时触发了事件,则事件将丢失。希望HTMLTrackElement具有readyState属性,可以检查该属性以了解加载状态。

这样的东西应该可以工作,它会附加处理程序来处理后续的加载事件,如果当前加载了轨道,它也会立即调用回调。

function whenLoaded(track, callback) {
    const LOADED = 2;

    track.addEventListener('load', callback);
    if (track.readyState === LOADED) callback();
}

答案 1 :(得分:0)

您的代码非常有效,如下所示。我只是将事件从加载更改为单击并在foo之前添加了函数字。

&#13;
&#13;
function foo(div) {
  div.addEventListener('click', function() {
    console.log('this loads');
  });
};


var div = document.getElementById('main');
  
setTimeout(function() {
  foo(div);
}, 1000);
&#13;
#main {
  background-color: red;
  width: 100px;
  height: 100px;
}
&#13;
<div id="main"></div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

请注意,如果未在load元素设置default属性,则不会对chrome,chrome触发<track>事件。

不确定您是要更改现有src元素的<track>还是将新<track>元素添加到父<video>元素?

以下方法将新<track>元素附加到<video>元素。将src传递给foo,将load事件附加到track元素,然后追加到父<video>元素,将<track>元素附加到{{1} }},然后将<video>设置为传递给src

的变量
foo

答案 3 :(得分:0)

来自你的后续评论:

  

目标是让此功能与动态添加的内容一起使用。

使事件侦听器使用动态内容的最佳解决方案是事件委派。在添加该元素之后,您不必担心将事件侦听器添加到动态元素,而只需将事件侦听器添加到该元素的,其中该父元素已存在于文档中。或者你可以使用祖父母,曾祖父母等。如果你没有更具体的元素可以使用,你甚至可以一直到body元素。

您可以在加载动态内容之前添加此事件侦听器,因为您要在现有元素上添加它。

调用事件侦听器时,event.target是对触发事件的实际元素的引用。所以你检查一下,看看它是否是你想要实际处理事件的元素之一。

this question的答案有一些如何使用事件委派的好例子。它非常简单,通过监听动态添加内容的事件来解决每个问题。