当前位置: 首页 > 知识库问答 >
问题:

避免我在脚本中创建8 addEventListener

施刚毅
2023-03-14

我只是一个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个答案

穆宾白
2023-03-14

新的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");
  }
});
css lang-css prettyprint-override">.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>
 类似资料:
  • Hyperf 提供了创建模型的命令,您可以很方便的根据数据表创建对应模型。命令通过 AST 生成模型,所以当您增加了某些方法后,也可以使用脚本方便的重置模型。 php bin/hyperf.php gen:model table_name 创建模型 可选参数如下: 参数 类型 默认值 备注 --pool string default 连接池,脚本会根据当前连接池配置创建 --path strin

  • 我有一个弹性查询脚本,用于使用我给出的参数计算地面距离,我必须在多个查询中使用它。是否有一种方法可以避免这种重复,例如,有一种计算全局变量并在所有脚本中使用它的方法。在本例中,我希望计算<code>距离 映射:

  • 由Autoconf生成的配置脚本通常被称为configure。在运行的时候,configure 创建一些文件,在这些文件中以适当的值替换配置参数。由configure创建的文件有: 一个或者多个'Makefile'文件,在包的每个子目录中都有一个(参见 Makefile中的替换 ) 有时创建一个C头文件,它的名字可以被配置,该头文件包含一些#define命令 (参见 配置头文件 ) 一个名为'co

  • 创建组件脚本 在 Cocos Creator 3D 中,脚本也是资源的一部分。你可以在资源编辑器中通过点击"创建"按钮来添加并选择 TypeScript 来创建一份组件脚本。此时你会在你的资源编辑器中得到一份新的脚本: 一份简单的组件脚本如下: import { _decorator, Component, Node } from 'cc'; const { ccclass, property }

  • 问题内容: 我们有一个相当简单的node.js应用程序,但是由于AWS Elastic Beanstalk部署机制,即使提交了一个文件,也需要大约5分钟(通过)推出新版本。 即,提交本身(和上载)非常快(仅可推送1个文件),但是Elastic Beanstalk从S3获取整个包,将其解压缩并运行,这导致node-gyp编译一些模块。安装/构建完成后,Elastic Beanstalk会擦除并用新的

  • 问题内容: 我会解释一个模糊的标题。 我正在编写一个SQL脚本来为数据库中表的每一行创建一个插入语句,纯粹是为了能够将该数据应用回另一个数据库。 这是我目前所拥有的: 它的效果很好,输出如下: 问题是,如果字段之一为空,则该行将无法生成更新脚本,在输出文件中,该行仅是空白。显然,由于有20多个字段,因此一些可选内容意味着几乎不会生成我的任何脚本。 有没有办法解决这个问题? 问题答案: 对于NULL