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

yizhihongxing

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 在数组插入字符的实现代码(可参考JavaScript splice() 方法)

    下面是详细的攻略: 什么是 splice() 方法 JavaScript 中的 splice() 方法是用来在数组中插入/删除元素的方法。其语法如下: array.splice(start, deleteCount, item1, item2, …) 其中, start:指定插入/删除元素的位置,从 0 开始计数。 deleteCount:可选参数,指定…

    JavaScript 2023年5月27日
    00
  • 三种方法让Response.Redirect在新窗口打开

    当使用Response.Redirect方法时,页面会在当前浏览器窗口中打开跳转的页面,如果需要在新的窗口中打开跳转页面,可以采用以下三种方法: 1. 在服务器端页面上使用ClientScript.RegisterStartupScript方法 使用ClientScript.RegisterStartupScript方法可以在服务器端页面上注册启动JavaS…

    JavaScript 2023年6月11日
    00
  • Ajax提交post请求案例分析

    Ajax提交Post请求的完整攻略 什么是Ajax提交Post请求? Ajax是Asynchronous JavaScript and XML(异步的Javascript和XML)的缩写。它是一种用于创建更快、更好、更友好的Web应用程序的Web开发方法。 使用AJAX可以在不重新加载整个Web页面的情况下更新页面的内容。其中,Ajax的一种常见用法是通过P…

    JavaScript 2023年6月11日
    00
  • Javascript如何判断数据类型和数组类型

    Javascript中的数据类型包括Boolean、Number、String、Null、Undefined、Object、Symbol,其中Object中又包含了Array和Function等类型。我们可以通过typeof关键字来判断基本数据类型,而判断数组类型则需要稍微复杂一些。 判断基本数据类型 typeof关键字可以判断一个变量的基本数据类型,其用法…

    JavaScript 2023年5月27日
    00
  • 基于BootStrap与jQuery.validate实现表单提交校验功能

    下面我将为您详细讲解如何基于BootStrap和jQuery.validate实现表单提交校验功能。 1. 引入必要的库和样式文件 在页面中引入BootStrap和jQuery库和样式文件,以及jQuery.validate插件,例如: <!– 引入BootStrap样式文件 –> <link rel="stylesheet&…

    JavaScript 2023年6月10日
    00
  • javascript写的异步加载js文件函数(支持数组传参)

    让我详细讲解一下“javascript写的异步加载js文件函数(支持数组传参)”的完整攻略。 1. 异步加载JS文件的必要性 在网页开发中,我们经常需要引入一些外部的JS文件。正常情况下,我们通过在HTML页面的<head>标签或者<body>标签中添加<script>标签来实现JS文件的载入。但是,如果我们需要引入多个J…

    JavaScript 2023年5月27日
    00
  • 跨平台移动WEB应用开发框架iMAG入门教程

    跨平台移动WEB应用开发框架iMAG入门教程 什么是iMAG iMAG是一款基于HTML5技术开发出的跨平台移动Web应用开发框架,它可以让开发者使用Web技术开发出安装在iOS、Android、Windows Phone等移动终端设备的应用。使用iMAG框架,开发者无需学习Objective-C、Java等编程语言,只需掌握HTML、CSS和JavaScr…

    JavaScript 2023年6月10日
    00
  • JS 密码强度校验的正则表达式(简单且好用)

    下面是详细讲解“JS 密码强度校验的正则表达式(简单且好用)”的完整攻略。 1. 背景和需求 现在几乎所有的网站都需要用户进行注册和登录操作,为了保障用户账号的安全,往往都需要在密码设置时进行一定的限制和校验,例如要求密码长度不少于6位,必须包含数字、字母和特殊字符等。 这时候,就可以使用正则表达式来进行密码强度的校验。而在实际应用中,可以针对不同的强度要求…

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