【问题标题】:addeventlistener to a dynamically generated element triggers event on all dynamically generated elements after himaddeventlistener 到一个动态生成的元素触发他之后所有动态生成的元素的事件
【发布时间】:2023-04-01 12:31:01
【问题描述】:

我有一个网页,我在其中添加了突出显示文本特定部分的可能性。每当我选择一些文本并按 ctrl+c 时,选定的文本都会插入到 span 中并突出显示。 当元素被突出显示时,HTML 看起来像这样。

  <div id ="text">
      <p>
    Vestibulum ante ipsum primis in faucibus orci "<span class="highlight" id="0">luctus</span>
 "et ultrices posuere cubilia Curae;" </p>

我正在尝试创建一个功能以在单击跨度时更改突出显示的颜色。

为此,我在下面创建了一个每次突出显示新元素时调用的函数。它选择文本中的所有跨度,应该选择相关的跨度,这要归功于其 ID 以更改其类,并添加事件侦听器。

function eventHighlighted() {

  //select all spans within the text into an HTML collection.
  let textToAnnotate = document.querySelector('#text');
  let spansExisting = textToAnnotate.querySelectorAll('span');    

 // function to change the highlighted colour
  function changeColour () {
    let selectedText = document.getElementsByClassName("highlight")[this.id];
    selectedText.className = "highlight-clicked";
    }

// add eventListener to all spans.
  for (var i = 0; i < spansExisting.length; i++) {
     var existingSpan = spansExisting[i];
     existingSpan.addEventListener("click", changeColour);
     }
  }

每次突出显示新的文本位时都会调用此函数。 (我认为这不是非常节省内存,因为它可能会在一些不再需要的跨度上添加不必要的事件侦听器。)

我遇到的问题是它对于突出显示的第一个元素效果很好。每当我点击这段突出显示的文本时,突出显示的颜色就会改变。

但是,当我突出显示第二个文本时,例如在这个例子中

 <div id ="text">
          <p>
        Vestibulum ante ipsum primis in faucibus orci "<span class="highlight" id="0">luctus</span>
     "et ultrices" <span class="highlight" id="1">posuere cubilia</span> " Curae;" </p>

如果我单击第一个跨度(luctus),它将触发其上的类更改,但也会触发下面的第二个跨度。 但是,当我选择第二个时,它将按预期工作,并且只会在第二个跨度上触发类更改。

我真的不知道为什么。我收集在第一个跨度上触发的函数实际上指示他更改 HTML 集合中所有跨度的类。我不明白为什么它没有指示他专门为他做这件事。

谢谢!

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您不需要 span 标签中的额外属性。看看我的解决方案。希望这会有所帮助。

    function initHighlights() {
      var highlights = document.querySelectorAll('.highlight');
    
      for (var i = 0; i < highlights.length; i++) {
        highlights[i].onclick = function() {
          // this - refers to span HTMLElement
          this.classList.toggle("highlight-clicked");
        };
      }
    }
    
    initHighlights();
    .highlight {
      background: lightgrey;
      cursor: pointer;
      user-select: none;
    }
    
    .highlight-clicked {
      background: yellow;
    }
    <div id ="text">
        <p>Vestibulum ante ipsum primis in faucibus orci "<span class="highlight">luctus</span>"et ultrices <span class="highlight">posuere cubilia</span> Curae;"</p>
    </div>

    【讨论】:

    • 您能否解释一下我最初的编码中发生了什么?我很想了解它背后的逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多