我有一个元素属性从第三方注入我的页面:
document.querySelector('#embed-container #mf2-events').jsMF2
jsMF2表示注入属性。我需要等到定义jsMF2属性才能使用它。最初,我只是设置了超时,但出于多种原因这是不可取的。有没有办法可以旋转到属性或设置回调?如果这是一个C程序,我会写这样的东西:
while (document.querySelector('#embed-container #mf2-events').jsMF2 === undefined ||
document.querySelector('#embed-container #mf2-events').jsMF2 === null) { }
// do work
答案 0 :(得分:4)
您不希望忙碌等待,因为之后没有其他JavaScript可以运行(更不用说浏览器UI的大部分内容),因此该属性不会被定义。
理想情况下,无论提供该属性的是什么,它都会触发您可以挂钩的事件。我会假设你看起来并没有找到一个。 : - )
一旦对ECMAScript6(又称“ES6”)中最新内容的支持变得普遍(目前不是这样),您可能能够使用Proxy
来实现此目的(提供您的目标浏览器在其HTML元素实例上允许Proxy
。但是对Proxy
的广泛支持将花费几年时间(如果不长)(并且Proxy
无法填充/填充)。 (在ES7中,您可以使用Object.observe
,但可能Proxy
由当前[截至2015年6月]标准定义,在ES7技术出现之前将得到广泛支持。)
除非您可以使用Proxy
,否则计时器确实是处理这种情况的正确方法。如有必要,它可以是一个非常积极的计时器。
如果已知元素存在,但您正在等待该属性:
check(function(element) {
// It's there now, use it
// x = element.jsMF2
});
function check(callback) {
var element = document.querySelector('#embed-container #mf2-events');
if (element && 'jsMF2' in element) {
setTimeout(callback.bind(null, element), 0);
} else {
setTimeout(check.bind(null, callback), 0);
}
}
当JavaScript线程在前几次可用时,大多数浏览器会立即触发该计时器 ,然后将其限制为至少4ms延迟以便后续调用。还是很快。
但是,你不必过于激进;与计算机相比,人类很慢,你可能会使用10秒,20秒甚至50毫秒。如果任何机会不会出现该属性,您希望最终停止重复的setTimeout
系列(一秒钟后,10秒后,30秒后,之后) 60秒,适合您的用例)。你可以通过记住你什么时候开始,然后干脆而不是重新安排它来做到这一点:
var started = Date.now();
check(function(element) {
// It's there now, use it
// x = element.jsMF2
});
function check(callback) {
var element = document.querySelector('#embed-container #mf2-events');
if (element && 'jsMF2' in element) {
setTimeout(callback.bind(null, element), 0);
} else {
if (Date.now() - started > 1000) { // 1000ms = one second
// Fail with message
} else {
setTimeout(check.bind(null, callback), 0);
}
}
}
旁注:查询
var document.querySelector('#embed-container #mf2-events');
......有点奇怪。它说:给我第一个元素,id
mf2-events
在id
embed-container
的元素中找到。但id
值必须在页面上是唯一的。所以真正说的是“获取#mfs-events
元素,但前提是它只在#embed-container
元素内。”
除非那个真的你的意思,否则显着更快
var document.getElementById('mf2-events');
......将是要走的路。
答案 1 :(得分:0)
这里唯一真正的方法是使用回调。该物业如何设定?如果它是由ajax请求设置的,则需要添加一个函数作为请求参数,该参数将在满足请求时运行。您可能需要的主题是回调,异步JavaScript和承诺,这是异步马蹄莲的现代方法。
答案 2 :(得分:-1)
DOM Events不是很受欢迎,后来又用新标准MutationObserver取代。
但你应check if your target browser support it或同时实施两者。
编辑:如果属性不是dom属性,您也可以使用Object.observe()。