簡體   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