代码之家  ›  专栏  ›  技术社区  ›  Cain Nuke

setTimeout会多次执行相同的函数

  •  0
  • Cain Nuke  · 技术社区  · 6 年前

    我有这个代码:

    document.addEventListener("DOMContentLoaded", function(event) {
      // Select the node that will be observed for mutations
      var parentOfMyList = document.body;
    
      // Options for the observer (which mutations to observe)
      var config = {
        attributes: true,
        childList: true,
        subtree: true
      };
    
      // Callback function to execute when mutations are observed
      var callback = function(mutationsList) {
        for (var mutation of mutationsList) {
          if (mutation.type == 'childList') {
    
            if (document.getElementById("topcmm-123flashchat-main-toolbar-message-type-option") != null) {
              var elt = document.getElementById("topcmm-123flashchat-main-toolbar-message-type-option");
              setTimeout(elt.click.bind(elt), 2000);
              if (document.getElementById("topcmm-123flashchat-toolbar-style-send-sound-btn") != null) {
                var clic2 = document.getElementById("topcmm-123flashchat-toolbar-style-send-sound-btn");
                setTimeout(clic2.click.bind(clic2), 2100);
                if (document.getElementById("topcmm-123flashchat-send-message-panel-close-icon") != null) {
                  var clic3 = document.getElementById("topcmm-123flashchat-send-message-panel-close-icon");
                  setTimeout(clic3.click.bind(clic3), 2200);
    
                  //execute some function
                }
              }
            }
          }
        }
      };
    
      // Create an observer instance linked to the callback function
      var observer = new MutationObserver(callback);
      observer.observe(parentOfMyList, config);
    });

    代码应该执行一些函数(为了方便起见不包括在这里),直到 topcmm-123flashchat-sound-messages-contents 出现在dom中,直到 topcmm-123flashchat-toolbar-style-send-sound-btn 出现并被单击,并且这个也不会出现在dom中,直到 topcmm-123flashchat-main-toolbar-message-type-option 出现并单击。

    因此,我编写了上面的代码,以便自动地逐个单击元素,并将它们显示在DOM中,以便执行问题中的函数。

    topcmm-123flashchat-main-toolbar-message-type-选项 将在页面加载后3秒后自动显示,如果单击,则 topcmm-123flashchat-toolbar-style-send-sound-btn 将出现,如果单击该选项,则 topcmm-123flashchat-sound-messages-contents公司 将出现并执行功能。我另外还有 topcmm-123flashchat-send-message-panel-close-icon 单击以关闭以前单击打开的面板。

    这里的问题是面板一直打开,就像 elt click2 被执行过多次, click3 似乎没有被处决。为什么?

    谢谢您。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Barmar    6 年前

    您需要添加逻辑以防止对以前添加的元素重复相同的操作。

    我添加了一个保存元素的变量。第一次看到元素时,变量为空,因此 if 代码运行。它在以后的跑步中被跳过。

    document.addEventListener("DOMContentLoaded", function(event) {
      // Select the node that will be observed for mutations
      var parentOfMyList = document.body;
    
      // Options for the observer (which mutations to observe)
      var config = {
        attributes: true,
        childList: true,
        subtree: true
      };
    
      var elt = null,
        clic2 = null,
        clic3 = null;
      // Callback function to execute when mutations are observed
      var callback = function(mutationsList) {
        for (var mutation of mutationsList) {
          if (mutation.type == 'childList') {
            if (!elt && (elt = document.getElementById("topcmm-123flashchat-main-toolbar-message-type-option"))) {
              setTimeout(elt.click.bind(elt), 2000);
            }
            if (!clic2 && (clic2 = document.getElementById("topcmm-123flashchat-toolbar-style-send-sound-btn"))) {
              setTimeout(clic2.click.bind(clic2), 2100);
            }
            if (!clic3 && (clic3 = document.getElementById("topcmm-123flashchat-send-message-panel-close-icon"))) {
              setTimeout(clic3.click.bind(clic3), 2200);
            }
          }
          break;
        }
      };
    
      // Create an observer instance linked to the callback function
      var observer = new MutationObserver(callback);
      observer.observe(parentOfMyList, config);
    
      // other code can go here
    });