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日

相关文章

  • JS异步代码单元测试之神奇的Promise

    JS异步代码单元测试一直是开发人员要面对的挑战。为了解决这个问题,Promise异步编程模式被引入到JavaScript中,因其简单、灵活和可重用性而受到广泛认可。在本攻略中,我们将深入探讨如何在单元测试中使用Promise,以及如何跟踪异步代码逻辑和处理可能的异步回调。 异步单元测试面临的问题 在传统的单元测试中,我们可以通过直接调用函数、对函数输出结果进…

    JavaScript 2023年5月28日
    00
  • 详解javascript表单的Ajax提交插件的使用

    详解Javascript表单的Ajax提交插件的使用 1. AJAX 是什么? AJAX 即 Asynchronous Javascript And XML (异步 JavaScript 和 XML)。在不重新加载整个页面的情况下,可以通过 AJAX 在后台与服务器进行数据交互。使用 AJAX,可以实现异步加载数据,提高用户体验。 2. 表单提交流程 在传统…

    JavaScript 2023年6月11日
    00
  • HTML DOM setInterval和clearInterval方法案例详解

    下面我将详细讲解“HTML DOM setInterval和clearInterval方法案例详解”的完整攻略。 1. 回顾setInterval和clearInterval的概念 在深入讲解之前,我们需要先了解setInterval和clearInterval两个函数的基本概念。 setInterval:可以重复执行一个函数或一段代码,在规定的时间间隔内不…

    JavaScript 2023年6月11日
    00
  • js 转义字符及URI编码详解

    JS 转义字符及 URI 编码详解 在 JavaScript 编程中,我们经常需要对一些字符进行编码或转义,以确保它们能够被正确地处理和显示。同时,对于某些需要作为 URL 参数传递的字符,也需要使用 URI 编码进行处理。本攻略将就这两个问题进行详细的讲解。 转义字符 在 JavaScript 中,我们可以通过使用转义字符来表示一些特定的字符。下表列出了一…

    JavaScript 2023年5月20日
    00
  • javascript请求servlet实现ajax示例(分享)

    下面我来详细讲解“javascript请求servlet实现ajax示例(分享)”的完整攻略。 什么是 Ajax? Ajax 指的是一种创建交互式、快速动态网页的技术。利用 Ajax,在不重新加载整个页面的情况下,实现局部更新数据的功能,并且不会打断用户正在进行的操作。 实现 Ajax 的方式 实现 Ajax 的方式有很多,其中比较典型的方式就是使用 Jav…

    JavaScript 2023年6月11日
    00
  • js 判断字符串中是否包含某个字符串的实现代码

    实现 JavaScript 判断一个字符串是否包含另一个字符串,我们可以使用 String 类型自带的 includes() 方法、indexOf() 方法和正则表达式,以下依次进行详细讲解和代码演示。 includes() 方法 includes() 方法用于判断一个字符串是否包含另一个字符串,返回值为布尔值。 语法: str.includes(searc…

    JavaScript 2023年5月28日
    00
  • JavaScript高级程序设计之变量与作用域

    JavaScript高级程序设计中的变量和作用域是一个基础而又重要的概念。下面是一个详细的攻略,帮助你深入理解变量和作用域。 变量 声明变量 声明变量是在程序中创建变量的过程。在JavaScript中,可以使用三种关键字来声明变量: var let const 其中,var是ES5的语法,let和const是ES6的语法。使用var定义的变量的作用域是在函数…

    JavaScript 2023年5月27日
    00
  • 如何开发一个渐进式Web应用程序PWA

    如何开发一个渐进式Web应用程序(PWA)的完整攻略主要包含以下步骤: 1. 确定应用程序的功能 在开发PWA之前,我们需要明确我们的应用程序所需要实现的功能。这样有助于我们更好地明确开发的方向和目标。 2. 设计您的应用程序的用户界面 设计好应用程序的用户界面是非常重要的。因为它直接影响用户对您的应用程序的使用体验。 3. 选择合适的PWA框架 目前,有许…

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