setTimeout keeps executing the same function many times

寵の児 提交于 2019-12-24 18:23:36

问题


I have this code:

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);
});

the code is supposed to execute some function (not included here for the sake of convenience) which cant be executed until topcmm-123flashchat-sound-messages-contents is present in DOM which wont appear until topcmm-123flashchat-toolbar-style-send-sound-btn appears and is clicked, and this one wont appear in DOM either until topcmm-123flashchat-main-toolbar-message-type-option appears and is clicked as well.

So I wrote the code above in order to automatically click on the elements one after another and have them appear in the DOM so the function in questions can be executed.

topcmm-123flashchat-main-toolbar-message-type-option will appear by itself about 3 seconds later after the page loads, if clicked then topcmm-123flashchat-toolbar-style-send-sound-btn will appear and if that one is clicked then topcmm-123flashchat-sound-messages-contents will appear and the function will be executed. I additionally have topcmm-123flashchat-send-message-panel-close-icon clicked in order to have the panels that opened with the previous clicks closed.

The problem here is the panels keep opening like if elt and click2 are executed many times whereas click3 doesnt seem to be executed. Why is that?

Thank you.


回答1:


You need to add logic to prevent repeating the same action for an element that was added previously.

I've added a variable that holds the element. The first time the element is seen, the variable empty, so the if code runs. It's skipped on future runs.

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
});


来源:https://stackoverflow.com/questions/51468755/settimeout-keeps-executing-the-same-function-many-times

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!