Javascript:addEventListener 仅在 setTimeout 中工作



我正在尝试设置事件侦听器,但只有在 setTimeout 中设置它们时才有效。

不起作用:

WebApp.setController('jobs', function() {
  WebApp.setView('header', 'header');
  WebApp.setView('nav', 'nav');
  WebApp.setView('jobs', 'main');
  var jobs = document.querySelectorAll('.jobs-category');
  for(let i = 0; i < jobs.length; i++)
  {
    console.log('events added');
    jobs[i].addEventListener("dragover", function( event ) {
      console.log('drag over');
      event.preventDefault();
    });
    jobs[i].addEventListener('drop', function(event) {
      event.preventDefault();
      console.log('dropped');
    }, false);
  }
});

确实有效:

WebApp.setController('jobs', function() {
  WebApp.setView('header', 'header');
  WebApp.setView('nav', 'nav');
  WebApp.setView('jobs', 'main');
  window.setTimeout(function() {
    var jobs = document.querySelectorAll('.jobs-category');
    for(let i = 0; i < jobs.length; i++)
    {
      console.log('events added');
      jobs[i].addEventListener("dragover", function( event ) {
        console.log('drag over');
        event.preventDefault();
      });
      jobs[i].addEventListener('drop', function(event) {
        event.preventDefault();
        console.log('dropped');
      }, false);
    }
  }, 1);
});

(只有设置时间不同/另外)

setController() 保存函数并在路由被请求时执行它。

setView() 将 HTML5-templates 绑定到 DOM:

  var Template = document.querySelector('#' + Name);
  var Clone = document.importNode(Template.content, true);
  var CloneElement = document.createElement('div');
  CloneElement.appendChild(Clone);
  CloneElement = this.replacePlaceholders(CloneElement);
  document.querySelector(Element).innerHTML = CloneElement.innerHTML;

为什么这只在 setTimeout 中有效?我认为javascript是同步的。

另外:这是一个单页应用程序,在 DOM 准备就绪后已经加载。

你的Javascript在页面中的什么位置?

我的猜测是,当您尝试注册事件时,HTML尚未准备就绪,这就是为什么它仅适用于setTimeout

尝试在页面底部(在 HTML 之后)包含您的 javascript,或者侦听页面加载事件。有关如何执行此操作的信息,请参阅此问题 - $(document).ready 等效物,无需 jQuery。

根据您对同步javascript的假设 - 是的,它(大部分)是浏览器呈现页面的方式(除非使用脚本加载async)。这意味着JavaScript之后的HTML将不可用。

更新 - 根据您使用单页应用程序的评论,您必须侦听加载完成/完成/成功事件。绕过它的另一种方法是侦听父元素(始终存在)上的事件。

希望这有帮助。

 document.addEventListener("DOMContentLoaded",      function(event) { 
   //do work
});

很可能您在 html 内容之前加载 JS 文件。在 DOM 准备就绪之前,您无法运行 Javascript 函数。

最新更新