向一个在javascript中还不存在的元素添加一个事件监听器

Adding an event listener to an element that doesn't exist yet in vanilla javascript

本文关键字:一个 元素 添加 监听器 事件 javascript 不存在      更新时间:2023-09-26

在JQuery中我可以这样做:

$(document).on("click","a.someBtn",function(e){
    console.log("hi");
});

向尚不存在的元素添加事件侦听器。我似乎无法弄清楚如何将事件侦听器添加到在普通javascript中尚未存在的元素中。
下面的代码显然不能工作:

query.addEventListener( "click", someListener );

编辑

我想做的是通过查询选择器比较项。我选择的是querySelectorAll中还不存在的元素。它比仅仅检查标记名称要动态一些。

使用event对象中的target属性来获取被单击的元素。然后,手动测试类型/attributes/ids

document.addEventListener( "click", someListener );
function someListener(event){
    var element = event.target;
    if(element.tagName == 'A' && element.classList.contains("someBtn")){
        console.log("hi");
    }
}

您可以使用event.target

发送事件的对象的引用。

<

代码/em>

(function () {
    "use strict";
        document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
        if (e.target.tagName == 'A' && e.target.classList.contains("someBtn")) {
          alert('Clicked');
        }
      }, false);
})();

(function() {
  "use strict";
  var a = document.createElement('a');
  a.textContent = 'Click Me';
  a.href = '#';
  document.body.appendChild(a);
  document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
    if (e.target.tagName == 'A') {
      alert('Clicked');
    }
  }, false);
})();

您需要使用DOM MutationObserver Events来应用addEventListener。自2012年以来,我认为所有主要浏览器都可以使用这个DOM API。

我用这个来降低由他们的代码片段(https://www.w3schools.com/howto/howto_google_translate.asp)创建的谷歌翻译工具栏。由于它是动态创建元素(iframe),所以遇到的问题与您遇到的问题相同。只需根据需要更改回调函数和变量。

//Observer for Google translator bar creation and action to move to bottom
// Select the nodetree that will be observed for mutations
var nodetree = document.getElementsByTagName("body")[0];
// Select the target node atributes (CSS selector)
var targetNode = "iframe.goog-te-banner-frame";
// Options for the observer (which mutations to observe)
var config = { attributes: false, childList: true };
// Callback function to execute when mutations of DOM tree are observed
var lowerGoogleTranslateBar = function(mutations_on_DOMtree) {
    for(var mutation of mutations_on_DOMtree) {
        if (mutation.type == 'childList') {
            console.log(mutation);
            if (document.querySelector(targetNode) != null) {
                //40px is the height of the bar
                document.querySelector(targetNode).style.setProperty("top", "calc(100% - 40px)");
                //after action is done, disconnect the observer from the nodetree
                observerGoogleTranslator.disconnect();
            }
        }
    }
};
// Create an observer instance linked to the callback function
var observerGoogleTranslator = new MutationObserver(lowerGoogleTranslateBar);
// Start observing the target node for configured mutations
observerGoogleTranslator.observe(nodetree, config);

您可以在这里了解更多信息:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

这是一个可以让你像jQuery的.on一样添加"live"事件的函数。它可以像这样调用:

addLiveListener(scope, selector, event, function reference);

查看函数注释,了解每个参数的描述。

/**
 * Adds a istener for specific tags for elements that may not yet
 * exist.
 * @param scope a reference to an element to look for elements in (i.e. document)
 * @param selector the selector in form [tag].[class] (i.e. a.someBtn)
 * @param event and event (i.e. click)
 * @param funct a function reference to execute on an event
 */
function addLiveListener(scope, selector, event, funct) {
  /**
   * Set up interval to check for new items that do not 
   * have listeners yet. This will execute every 1/10 second and
   * apply listeners to 
   */
  setInterval(function() {
    var selectorParts = selector.split('.');
    var tag = selectorParts.shift();
    var className;
    if (selectorParts.length)
      className = selectorParts.shift();
    if (tag != "") {
      tag = tag.toUpperCase();
      var elements = scope.getElementsByTagName(tag);
    } else
      var elements = scope.getElementsByClassName(className);
    for (var i = 0; i < elements.length; i++) {
      if (elements[i][event + '_processed'] === undefined && (tag == "" || elements[i].tagName == tag)) {
        elements[i].addEventListener(event, funct);
      }
    }
  }, 1000);
}

这里是一个完整的工作演示:

/**
 * Adds another anchor with no events attached and lets 
 * our other code auto-attach events
 */
var currentAnchor = 3;
function addAnchor() {
  currentAnchor++;
  var element = document.createElement('a');
  element.href = "#";
  element.innerHTML = "Anchor " + currentAnchor;
  element.className = "someBtn";
  document.getElementById("holder").appendChild(element);
}
/**
 * Adds a istener for specific tags for elements that may not yet
 * exist.
 * @param scope a reference to an element to look for elements in (i.e. document)
 * @param selector the selector in form [tag].[class] (i.e. a.someBtn)
 * @param event and event (i.e. click)
 * @param funct a function reference to execute on an event
 */
function addLiveListener(scope, selector, event, funct) {
  /**
   * Set up interval to check for new items that do not 
   * have listeners yet. This will execute every 1/10 second and
   * apply listeners to 
   */
  setInterval(function() {
    var selectorParts = selector.split('.');
    var tag = selectorParts.shift();
    var className;
    if (selectorParts.length)
      className = selectorParts.shift();
    if (tag != "") {
      tag = tag.toUpperCase();
      var elements = scope.getElementsByTagName(tag);
    } else
      var elements = scope.getElementsByClassName(className);
    for (var i = 0; i < elements.length; i++) {
      if (elements[i][event + '_processed'] === undefined && (tag == "" || elements[i].tagName == tag)) {
        elements[i].addEventListener(event, funct);
      }
    }
  }, 1000);
}
/**
 * Now let's add live listener for "a" tags
 */
addLiveListener(document, "a.someBtn", "click", function() {
  alert('Clicked ' + this.innerHTML);
});
a {
  margin-right: 10px;
}
<!-- Add some pre-existing anchors -->
<p id="holder">
  <a href="#" class="someBtn">Anchor 1</a><a href="#" class="someBtn">Anchor 2</a><a href="#" class="someBtn">Anchor 3</a>
</p>
<!-- A button to add dynamic new anchors -->
<input type="button" value="Add anchor" onclick="addAnchor();" />