Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.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:等待元素的属性准备好继续_Javascript - Fatal编程技术网

javascript:等待元素的属性准备好继续

javascript:等待元素的属性准备好继续,javascript,Javascript,我有一个从第三方注入我的页面的元素属性: document.querySelector('#embed-container #mf2-events').jsMF2 jsMF2被称为注入属性。我需要等到定义了jsMF2属性之后才能使用它。最初,我只是设置了一个超时,但由于许多原因,这是不可取的。是否有一种方法可以旋转直到属性关闭或设置回调?如果这是一个C程序,我会这样写: while (document.querySelector('#embed-container #mf2-event

我有一个从第三方注入我的页面的元素属性:

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

您不希望等待很忙,因为这样就没有其他JavaScript可以运行(更不用说浏览器UI的大部分),因此不会定义属性

理想情况下,无论提供该属性的是什么,它都会触发一个事件,您可以将其挂钩。我假设你已经找过了,但没有找到。:-)

一旦ECMAScript6(也称为“ES6”)中对最新内容的支持变得广泛(目前还没有),您就可以使用它(前提是您的目标浏览器允许在其HTML元素实例上使用代理)。但是对
Proxy
的足够广泛的支持需要几年时间,如果不是更长的话(而且
Proxy
无法填充填充)。(在ES7中,您可以使用,但据推测,
Proxy
(由当前[截至2015年6月]标准定义)将在ES7技术推出之前得到广泛支持。)

除非您可以使用代理服务器,否则定时器确实是处理这种情况的正确方法。如果必要的话,它可以是一个非常有攻击性的计时器

如果已知元素存在,但您正在等待属性:

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事件
,在具有
id
嵌入容器
的元素中找到。但是
id
在页面上必须是唯一的。所以真正要说的是“获取
#mfs events
元素,但前提是它位于
#embed container
元素中。”

除非这真的是你的意思,否则速度越快

var document.getElementById('mf2-events');

…将是一种方法。

唯一真正的解决方法是使用回调。属性是如何设置的?如果它是由ajax请求设置的,那么您需要添加一个函数作为请求参数,当请求得到满足时将运行该参数。您可能需要的主题是回调、异步JavaScript和可能的承诺,它们是异步回调的现代方法。

有一些不太流行,后来用新标准取代了它们

但您应该选择或同时实现这两种方法



编辑:如果属性不是dom属性,也可以使用。

您的意思是在多线程C程序中,您会这样做。浏览器中的JavaScript(除了用作web Worker时)实际上是在单个线程上运行的。您需要使用
setTimeout()
进行轮询,或者可以在现代浏览器中使用。在
循环中旋转只会锁定浏览器,它永远不会成功,因为没有其他代码可以运行以实际导致更改发生。@user3689167:对,但是如果程序是真正的单线程程序,它将永远忙着等待——因为没有任何程序有机会设置jsMF2。要在忙着等待时执行此操作,至少需要两个线程。我不确定如何设置该属性,它是通过第三方注入的,我无权访问该第三方请不要使用0设置超时。如果没有,它会烧电池CPU@DennisCheung:不,没有。显然,您不想永远这样做,但它只是在运行代码,就像任何其他程序运行代码一样。正确编码的
setTimeout(…,0)
的用例非常常见。确实如此。CPU睡眠时间越长,电池电量越少wasted@DennisCheung:再一次:它只是在适当的时间运行代码,做一些有用的事情。这就是全部。(这比忙碌的等待危害要小得多。)请不要再讲“不烧CPU就烧电池”的废话。“不要烧电池,即使做一些有用的事情”的逻辑结论是什么都不做。没有上下文,在第三方做出更改之前,你不知道“运行代码”在做什么。这意味着,它可能是一些网络负载、UI动画、CPU进程(您试图从中窃取CPU时间的任何进程)或用户交互。在大多数情况下,它只是消耗CPU和浪费。我使用setTimeout,0,但只在“修复愚蠢的执行顺序”时使用它,这样我就不会再轮询了。
jsMF2
不是突变观察者可以观察到的任何东西。这是expando的财产。变异观察者只能观察DOM更改。它从document.querySelector返回。这是一个家庭聚会。这是可以观察到的,试试看。是的,元素是DOM元素。这不会使expando属性成为可以观察到的DOM属性。想想看,你会告诉观察者要观察什么<代码>子列表
?它不是子节点<代码>属性
<代码>属性值<代码>属性过滤器?这不是一个属性<代码>字符数据<代码>字符数据旧值?这不是字符数据<代码>子树?再说一次,它不是一个节点。见鬼,即使是一些DOM定义的反射属性,也无法通过MutationObserver观察到,例如