javascript循环变量注册dom事件 之强大的闭包

JavaScript循环变量注册DOM事件之强大的闭包

前言

在 JavaScript 中,我们经常使用循环语句(如 for, while, do-while)来遍历数组、对象等集合类型的数据。在循环过程中,我们可能需要为集合中的每个元素注册某个 DOM 事件,如点击、鼠标悬浮等,为了实现这一目标,我们往往需要使用闭包的技巧。

闭包

在 JavaScript 中,闭包是指能够访问其他函数作用域内变量的函数。这是一种非常强大的编程技巧,在循环中注册 DOM 事件时也非常常用。

闭包的原理是:内部函数可以访问外部函数的变量,即便外部函数已经执行完毕,内部函数依然可以访问外部函数的变量。在循环中,我们需要创建一个闭包函数,以便为循环体内的每个元素注册 DOM 事件。

下面是一个示例:

let buttons = document.getElementsByTagName('button');

for (let i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', function() {
    console.log(i);
  });
}

上述代码会注册多个点击事件,每当点击某个 button 元素时,会在控制台输出 i 的值,但是这个值永远是循环结束后的最终值,而不是当前值。

为了解决这个问题,我们需要在循环内部创建一个闭包函数,并将当前 i 的值传递给它:

let buttons = document.getElementsByTagName('button');

for (let i = 0; i < buttons.length; i++) {
  (function(index){
    buttons[index].addEventListener('click', function() {
      console.log(index);
    });
  })(i);
}

在上述代码中,我们使用了立即调用函数表达式(Immediately-Invoked Function Expression,IIFE),将当前的 i 变量作为参数传递给闭包函数,使得每个闭包函数都拥有了独立的 i 值。

示例说明

示例一

下面是一个简单的示例,展示了如何使用闭包来为列表元素添加点击事件:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>闭包示例一:为列表元素添加点击事件</title>
</head>
<body>
  <ul>
    <li>Apples</li>
    <li>Bananas</li>
    <li>Cherries</li>
  </ul>
  <script>
    let items = document.getElementsByTagName('li');

    for (let i = 0; i < items.length; i++) {
      (function(index){
        items[index].addEventListener('click', function() {
          alert(items[index].textContent);
        });
      })(i);
    }
  </script>
</body>
</html>

在上述示例中,我们为列表元素添加了点击事件,当用户点击某个列表元素时,弹出一个对话框,显示该元素的文本内容。

示例二

下面是一个稍微复杂一些的示例,展示了如何使用闭包来为表格的表头和单元格添加点击事件:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>闭包示例二:为表格的表头和单元格添加点击事件</title>
  <style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
    }
    th, td {
      padding: 5px;
    }
    th {
      background-color: #eee;
    }
    td {
      background-color: #fff;
    }
  </style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>姓名</th>
        <th>年龄</th>
        <th>性别</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>小明</td>
        <td>18</td>
        <td>男</td>
      </tr>
      <tr>
        <td>小红</td>
        <td>20</td>
        <td>女</td>
      </tr>
      <tr>
        <td>小李</td>
        <td>22</td>
        <td>男</td>
      </tr>
    </tbody>
  </table>
  <script>
    let table = document.getElementsByTagName('table')[0];
    let rows = table.rows;
    let ths = rows[0].cells;

    for (let i = 0; i < ths.length; i++) {
      (function(index){
        ths[index].addEventListener('click', function() {
          alert(ths[index].textContent);
        });
      })(i);
    }

    for (let i = 0; i < rows.length; i++) {
      let tds = rows[i].cells;

      for (let j = 0; j < tds.length; j++) {
        (function(row, col) {
          tds[col].addEventListener('click', function() {
            alert(rows[row].cells[col].textContent);
          });
        })(i, j);
      }
    }
  </script>
</body>
</html>

在上述示例中,我们为表格的表头和单元格添加了点击事件。当用户点击表头或单元格时,弹出一个对话框,显示对应的文本内容。在循环中,我们使用了两级闭包,确保每个闭包函数都拥有了独立的行和列值。

总结

在循环中注册 DOM 事件时,一定要注意闭包的使用,否则会出现意想不到的问题。使用闭包,可以让每个循环体内的 DOM 元素都拥有独立的事件处理程序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript循环变量注册dom事件 之强大的闭包 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • JavaScript 如何在线解压 ZIP 文件

    若要在JavaScript中在线解压一个ZIP文件,可以使用一个名为jszip的JavaScript库。jszip可以通过NPM或通过CDN链接进行安装。 步骤 1:引入jszip库 安装jszip后,需要将其引入到你的项目中,可以通过如下方式: <script src="https://cdn.jsdelivr.net/npm/jszip/…

    JavaScript 2023年5月27日
    00
  • JavaScript实现Promise流程详解

    JavaScript实现Promise流程详解 什么是Promise? Promise是ES6中引入的一种异步编程解决方案,它将异步操作的结果包装成一个对象,从而让操作更加规范和便捷。Promise最大的特点就是解决了“回调地狱”问题。 Promise的基本用法 Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejec…

    JavaScript 2023年6月10日
    00
  • JAVA使用Gson解析json数据实例解析

    简介 JSON是一种轻量级的数据交换格式,很多时候我们需要在Java中使用JSON格式进行数据的传递或解析,在Java中使用Gson库可以方便地实现JSON的解析和生成。 Gson是Google提供的Java解析JSON的库,它可以将JSON字符串转化为Java对象,也可以将Java对象转化为JSON字符串。 基本概念 在使用Gson进行JSON解析时,需要…

    JavaScript 2023年6月11日
    00
  • JavaScript实现PC端横向轮播图

    下面是JavaScript实现PC端横向轮播图的完整攻略: 准备工作 要实现PC端横向轮播图,需要先准备好以下几点: HTML结构,即容器元素及其子元素,通常是一个div包裹符合数量的图片(img标签)。 CSS样式,如容器元素宽高、溢出隐藏、子元素浮动、统一宽高等。 JS代码,用来实现轮播图的滑动效果,具体实现方式后面会讲到。 实现步骤 确认容器元素的宽度…

    JavaScript 2023年6月11日
    00
  • 简单了解three.js 着色器材质

    了解three.js中着色器材质需要掌握一些基础知识,包括WebGL和着色器语言,以下是简要介绍: WebGL是一种基于浏览器的图形技术,使用GPU加速渲染三维图形,支持多种着色器材质。 着色器是一种程序,用于定制渲染模型的外观和行为,通过GPU进行加速渲染,包括片元着色器和顶点着色器两种类型。 three.js是WebGL的一个库,提供了主流的三维图形渲染…

    JavaScript 2023年6月10日
    00
  • 十个开发人员面临的最常见的JavaScript问题总结

    十个开发人员面临的最常见的JavaScript问题总结 问题一:变量作用域的问题 在JavaScript中,变量的作用域分为全局作用域和函数作用域。对于未声明的变量,如果将其赋值,它将自动成为全局变量。但是,这很容易导致命名冲突和意外赋值等问题。 解决方法:在JavaScript中,使用var、let和const关键字声明变量。使用var声明的变量具有函数作…

    JavaScript 2023年5月18日
    00
  • javascript实现跟随鼠标移动的图片

    以下是Javascript实现跟随鼠标移动的图片的完整攻略: 第一步:HTML 模板 首先,我们需要创建一个包含图片的 HTML 模板。可以按照以下示例来创建一个基本 HTML 模板: <!DOCTYPE html> <html> <head> <title>跟随鼠标移动的图片</title> &l…

    JavaScript 2023年6月11日
    00
  • 实例学习Javascript之构建方法、属性

    关于”实例学习Javascript之构建方法、属性”的攻略分享,可以分为以下几个部分来介绍。 什么是构建方法、属性 在JavaScript中,我们通常使用构造函数来创建对象,构造函数中的方法和属性也被称之为构建方法和构建属性。构建方法和属性是指通过构造函数创建出来的对象所具备的一些方法和属性。 如何定义构建方法、属性 通过定义构造函数,我们可以定义出一些构建…

    JavaScript 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部