我正在尝试设置事件侦听器,但只有在 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 函数。