Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setTimeout干扰加载事件处理程序的问题_Javascript_Dom Events_Settimeout_Race Condition - Fatal编程技术网

Javascript setTimeout干扰加载事件处理程序的问题

Javascript setTimeout干扰加载事件处理程序的问题,javascript,dom-events,settimeout,race-condition,Javascript,Dom Events,Settimeout,Race Condition,我在元素上附加了一个load事件处理程序。我如何确保即使在加载后附加处理程序,也能调用该处理程序 例如 正如您在下面所看到的,您的代码非常有效。我只是将事件从load改为click,并在foo之前添加了函数词 函数foo(div){ div.addEventListener('click',function(){ log('this loads'); }); }; var div=document.getElementById('main'); setTimeout(函数(){ 傅(分区);;

我在
元素上附加了一个
load
事件处理程序。我如何确保即使在
加载后附加处理程序,也能调用该处理程序

例如


正如您在下面所看到的,您的代码非常有效。我只是将事件从load改为click,并在foo之前添加了函数词

函数foo(div){
div.addEventListener('click',function(){
log('this loads');
});
};
var div=document.getElementById('main');
setTimeout(函数(){
傅(分区);;
}, 1000);
#主{
背景色:红色;
宽度:100px;
高度:100px;
}

注意,如果
元素未设置
默认属性,则不会在chrome、chrome上触发
加载事件

不确定您是否正在更改现有
元素的
src
,或将新的
元素附加到父
元素

下面的方法将一个新的
元素附加到
元素。将
src
传递到
foo
,将
load
事件附加到
track
元素,然后在附加到父
元素之前,将
元素附加到
元素,然后将
src
设置为传递到
foo
的变量

window.onload = function() {

  // append next `track` element to `video` in 1 seconds
  setTimeout(function() {
    // pass `src`, `label` to set at `track` element
    addTrack("/path/to/resource2", "track 1") 
  }, 1000);

  function foo(track, src) {  
    track.addEventListener("load", function() {
      console.log("this loads");
    });
    video.appendChild(track);
    track.src = src;
  };

  function addTrack(src, tracklabel) {
    var track = document.createElement("track");
    track.kind = "captions";
    track.srclang = "en";
    track.label = tracklabel;
    // set `default` attribute at `track` element
    track.setAttribute("default", "default");
    // pass `track` element, `src` to set at `track` to `foo`
    foo(track, src);
  }

  addTrack("/path/to/resource1", "track 1");

}

如果事件是在未连接侦听器的情况下触发的,则事件将丢失。希望
HTMLTrackElement
具有
readyState
属性,可以检查该属性以了解加载状态

类似的方法应该可以工作,它附加处理程序来处理后续的加载事件,如果当前加载了轨迹,它也会立即调用回调

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

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

从您的后续评论中:


我们的目标是让这个函数与动态添加的内容一起工作

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

您可以在加载动态内容之前添加此事件侦听器,因为您正在已存在的元素上添加它

调用事件侦听器时,
event.target
是对触发事件的实际元素的引用。因此,您需要检查它是否是您想要实际处理事件的元素之一


答案中有一些关于如何使用事件委派的好例子。它非常简单,解决了在动态添加的内容上侦听事件的所有问题。

您希望实现什么?目标是让此功能在动态添加内容时工作。一种情况是,用户在初始文档加载后使用函数foo,但问题是什么?是否未添加事件侦听器?这将继续向同一元素添加事件侦听器。根本不清楚你想解决什么问题。如果该元素实际上是一个
元素,那么它们没有加载事件…只有少数特殊的元素。事实证明,HTML中的元素存在这个问题。我通过使用track.readyState==2解决了这个问题,并在需要在不同时间加载时在那里加载事件。你们是对的,我需要更清楚一点!注意
load
事件不会冒泡。您需要收听捕获阶段。
function whenLoaded(track, callback) {
    const LOADED = 2;

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