提问者:小点点

避免我在脚本中创建8 addEventListener


我只是一个JavaScript的初学者,我需要您的帮助来优化我的代码。

这里的事实是,当我点击这个div:

<div class="sectionGrid__div--circle" id="lightboxBut_1">
    <img src="https://source.unsplash.com/100x100?mountain" alt="Mountain">
</div>

此脚本将被激活:

document.getElementById("lightboxBut_1").addEventListener("click", function() {
    console.log("lightboxBut_1");

    let lightbox_1 = document.getElementById("lightboxOpen_1"); 
    lightbox_1.style.display = "block";
});

最后在屏幕上显示一个div:

<div class="lightbox__container">
   <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 1</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Fugiat culpa neque dicta unde, repellendus consectetur a sit autem perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
</div>

实际上,它是工作的,但我需要这样做8次,因为我有8个按钮,必须显示8个不同的div在屏幕上。那么我如何才能优化我的脚本,避免做8个addEventListener呢?非常感谢您的帮助!!


共1个答案

匿名用户

新的web开发人员倾向于为他们的大多数HTML元素提供ID,因为您首先学到的一件事就是在JavaScript中使用.getElementByID()引用该元素是多么容易。不幸的是,这种做法不适合于扩展应用程序,并且会很快导致代码重复和高维护,因为每次添加或删除新的HTML元素时都必须添加/删除事件处理程序。

相反,ids在大多数情况下可以也不应该使用,相反,您可以通过许多其他方法定位元素(CSS类、文档中相对于其他元素的位置是最常见的)。

因此,这里有一个包含5个div元素的示例,每个元素都需要从自己的图像单击中激活,但最终有多少元素并不重要。当您从HTML中添加或删除一些内容时,JavaScript将不需要修改。

这种技术利用了“事件委派”,即事件从其源向上移动到文档对象模型的顶层,因此您只在比任何可能触发事件的元素更高的级别上设置一个处理程序,并在那里处理它。

顺便说一下,在下面的示例中,单击缩略图图像将取消隐藏它下面的lightbox,因为我使用的是.classlist.remove(“hidden”)。但是,如果您要使用.classlist.toggle(“hidden”),那么每次单击缩略图都会使lightbox隐藏(如果它已经显示,则显示)。

null

// Here's the key: instead of setting up a hander for each clickable element
// we just set up one at a common ancestor of all the clickable elements and
// wait for the event to bubble up to it and handle it here.

// All DOM event handlers will automatically be passed a reference to the event
// that triggered them so your event handler should be set up to recieve that
// argument. 
document.addEventListener("click", function(event) {
  // Check to see if the element that triggered the event is one we care about
  // The event object has a target property that references the actual eleement
  // that was the source for the event in the first place (an <img> with a class
  // of "source" is what we care about).
  if(event.target.classList.contains("source")){
    // It is, so just unhide its next sibling element
    event.target.nextElementSibling.classList.remove("hidden");
  }
});
.hidden  { display:none; }
<div class="sectionGrid__div--circle">
  <img src="https://source.unsplash.com/100x100?mountain" 
       alt="Mountain" class="source">
  
  <!-- By placing the element that is related to the image within the 
       same parent, it becomes very easy to locate it via a relative 
       location reference later. Also note that it has the hidden class
       by default so it will be initially hidden. -->
  <div class="lightbox__container hidden">
    <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 1</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      Fugiat culpa neque dicta unde, repellendus consectetur a sit autem
      perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure
      earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
  </div>
</div>

<div class="sectionGrid__div--circle">
  <img src="https://source.unsplash.com/100x100?mountain" 
       alt="Mountain" class="source">
  
  <div class="lightbox__container hidden">
    <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 2</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      Fugiat culpa neque dicta unde, repellendus consectetur a sit autem
      perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure
      earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
  </div>
</div>

<div class="sectionGrid__div--circle">
  <img src="https://source.unsplash.com/100x100?mountain" 
       alt="Mountain" class="source">
  
  <div class="lightbox__container hidden">
    <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 3</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      Fugiat culpa neque dicta unde, repellendus consectetur a sit autem
      perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure
      earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
  </div>
</div>

<div class="sectionGrid__div--circle">
  <img src="https://source.unsplash.com/100x100?mountain" 
       alt="Mountain" class="source">
  
  <div class="lightbox__container hidden">
    <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 4</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      Fugiat culpa neque dicta unde, repellendus consectetur a sit autem
      perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure
      earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
  </div>
</div>

<div class="sectionGrid__div--circle">
  <img src="https://source.unsplash.com/100x100?mountain" 
       alt="Mountain" class="source">

  <div class="lightbox__container hidden">
    <div class="lightbox__container--left">
      <h3 class="sstitleStyle">Lightbox 5</h3>
      <p class="paraStyle">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
      Fugiat culpa neque dicta unde, repellendus consectetur a sit autem
      perspiciatis tempore quasi odio earum ipsam assumenda. Aspernatur vel iure
      earum ad!</p>
   </div>
   <div class="lightbox__container--right">
       <img src="https://source.unsplash.com/500x500?mountain" alt="">
   </div>
  </div>
</div>