Typescript Jsdom如何;投票确定是否存在特定元素;?
在jsdom文档中,在异步脚本加载下,建议轮询特定元素的存在,作为确保dom加载所需内容的方法 以下代码是我对此的解释:Typescript Jsdom如何;投票确定是否存在特定元素;?,typescript,jsdom,Typescript,Jsdom,在jsdom文档中,在异步脚本加载下,建议轮询特定元素的存在,作为确保dom加载所需内容的方法 以下代码是我对此的解释: const elementOnPage = (arg: HTMLElement | null): HTMLElement => { let tried = arg; while (tried === null) { // debugger; console.log("nothing yet"); tried = arg; } re
const elementOnPage = (arg: HTMLElement | null): HTMLElement => {
let tried = arg;
while (tried === null) {
// debugger;
console.log("nothing yet");
tried = arg;
}
return tried;
};
然后调用函数,如下所示:
...
await elementOnPage(
dom.window.document.querySelector("#some element that I know will eventually be loaded onto the page")
);
...
尽管我知道这个元素最终会被加载,但这会导致一个无限循环。看起来这个参数可能第一次被计算为null,然后在以后的每一次都被设置为null,但我不确定。无论如何,我也试过使用
dom.window.document.getElementsByClassName("some class that will eventually have member elements")
并检查结果集合长度是否不是0,但这将返回相同的无限循环。我认为dom选择器方法不是问题所在。那么,是什么导致了这种无限循环,和/或是否有更好的方法来轮询元素?这里有一些误解:
elementOnPage(querySelector(…)
的调用执行一次(除非代码本身在某个循环或事件处理程序中)。如果DOM元素在执行时存在,它将立即返回,否则它将不再执行选择器,因此函数将以给定的参数null
无休止地运行while
这样的循环是阻塞的(这里不包括无关的工作线程),因此基本上是锁定线程。即使从循环内部重新运行querySelector
,也会导致无限循环承诺
(从技术上讲,您可以等待
任何东西,但承诺是您使其有用的手段)
以下是一个未经测试的示例:
const elementOnPage = (query: string, timeout: number = 10000): Promise<HTMLElement | null> => {
return new Promise((resolve, reject) => {
const startTime = Date.now();
const tryQuery = () => {
const elem = dom.window.document.querySelector(query);
if (elem) resolve(elem); // Found the element
else if (Date.now() - startTime > timeout) resolve(null); // Give up eventually
else setTimeout(tryQuery, 10); // check again every 10ms
}
tryQuery(); // Initial check
});
};
// Elsewhere:
const elem = await elementOnPage("#some_element");
const-elementOnPage=(查询:字符串,超时:number=10000):Promise=>{
返回新承诺((解决、拒绝)=>{
const startTime=Date.now();
const tryQuery=()=>{
const elem=dom.window.document.querySelector(查询);
if(elem)resolve(elem);//找到元素
如果(Date.now()-startTime>timeout)解析(null);//最终放弃
else setTimeout(tryQuery,10);//每10毫秒检查一次
}
tryQuery();//初始检查
});
};
//其他地方:
const elem=wait elementOnPage(“#某些#u元素”);
我明白了。这很有意义,因为我试图传递一个承诺,返回queryselector而不是选择器本身,但它似乎仍然返回一个无限循环。那么我如何确定要使用的间隔呢?只是随意的?假设我使用了2秒的间隔。这应该足够长,页面上的脚本可以加载,但如果连接速度非常慢,则不会加载。我添加了一个示例。您可以将检查间隔设置得非常小,比如每10毫秒甚至1毫秒检查一次(尽管实际执行不会那么精确)。只要你在一段时间内完成。