Javascript:addEventListener仅在setTimeout中工作

时间:2016-03-21 19:20:24

标签: javascript

我试图设置事件监听器,但只有在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);

});

(只有setTimout不同/另外)

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

setView()将HTML5模板绑定到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准备好后就已经加载了。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

页面中的Javascript在哪里?

我的猜测是,当您尝试注册该事件时,HTML还没有准备好,这就是为什么它只适用于setTimeout

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

根据您对同步javascript的假设 - 是的(主要是)它也是浏览器呈现页面的方式(除非使用async加载脚本)。这意味着javascript之后的HTML将无法使用。

更新 - 根据您对使用单页应用的评论,您必须收听加载完成/完成/成功事件。另一种绕过它的方法是监听父元素上的事件(总是在那里)。

希望这有帮助。