繁体   English   中英

递归异步检查html元素是否存在

[英]Recursively and asynchronously check if html element exists

我正在与一个网页进行交互,即使在文档准备好之后,子框架中的一些更深层次的嵌套元素也会加载 - 即它们依赖于在加载文档时尚未完成的未决 ajax/api 请求。

我的意图是等到这些元素存在后再对它们做任何事情。 我可以使用 setTimeout 执行此操作并在执行任何操作之前等待任意时间,例如

setTimeout(function() {
      $("#better_content .binder__toc").append(
        "<h4>Experiments</h4><ul><li>This</li><li>is</li><li>a</li><li>test</li></ul>"
      );
    }, 5000);

但是,最好以递归和异步(非阻塞)方式继续检查所述元素(“#better_content .binder__toc”),直到未定义或 null 未返回,即元素存在。 我尝试使用 Promises 来做到这一点。 一个带计数器的简单例子如下:

static waitForElement = counter => {

   counter++

    return new Promise((res, rej) => {
      if (counter < 5) {
        this.waitForElement(counter)
          .then(function() {
            res("complete");
          })
          .catch(rej);
      }
      res("complete");
    });
  };

this.waitForElement(counter)
      .then(a => console.log(a))
      .catch(a => console.log(a));

以上解决成功,似乎是非阻塞。 但是,如果我替换元素选择器的计数器如下:

static waitForElement = selector => {        

    let found = $(document).find(selector)[0];        
    console.log(found);

    return new Promise((res, rej) => {
      if (found === undefined) {
        this.waitForElement(selector)
          .then(function() {
            res("found");
          })
          .catch(rej);
      }
      res("found");
    });
  };


this.waitForElement("#better_content .binder__toc")
      .then(a => {
        console.log(a);
        $("#better_content .binder__toc").append(
          "<h4>Experiments</h4><ul><li>This</li><li>is</li><li>a</li><li>test</li></ul>"
        );
      })
      .catch(a => console.log(a));

然后这似乎永远不会成功解决并且确实减慢了网页的速度 - 我认为因为它仍然阻塞了主线程。

任何关于我如何纠正或理解这里发生的事情的建议都非常受欢迎。

您可以使用Mutation Observer API检查元素或元素子元素的更改。 API 会触发一个回调,您可以在其中断言您的逻辑在元素发生特定更改时采取行动。 在您的情况下,您将希望侦听将元素附加到fetch请求的容器。

可以侦听某些更改,例如属性更改,或者在您的情况下子项的更改。 在配置中添加childList: true这将表明您想要在添加或删除子项时执行某些操作。

这样您就不必检查元素是否存在。
查看下面的示例以查看您的示例。

 const target = document.getElementById('container'); const config = { childList: true }; const observer = new MutationObserver((mutations, observer) => { /** * Loop through all changes */ mutations.forEach(mutation => { /** * Only act if it is a change in the children. */ if (mutation.type !== 'childList') { return; } /** * Loop through the added elements and check if * it is the correct element. Then add HTML to * the newly added element. */ mutation.addedNodes.forEach(node => { if (node.id === 'content') { const html = ` <h4>Experiments</h4> <ul> <li>This</li> <li>is</li> <li>a</li ><li>test</li> </ul>`; node.innerHTML = html; } }); // Stop observing. observer.disconnect(); }); }); // Observe the children in container. observer.observe(target, config); // Add content element after 2 seconds. setTimeout(function() { const content = document.createElement('div'); content.id = 'content'; target.append(content); }, 2000);
 <div id="container"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM