zoukankan      html  css  js  c++  java
  • 给列表元素添加点击事件

    如下html代码,如何给一个列表中所有子元素添加点击事件,输出对应内容?

    <ul id="container">
    	<li id="li1">1</li>
    	<li id="li2">2</li>
    	<li id="li3">3</li>
    	<li id="li4">4</li>
    	<li id="li5">5</li>
    </ul>
    

    首先,循环列表,依次添加点击事件:

    for(var i = 1; i < 5; i++){
    	document.getElementById('li' + i).addEventListener('click', function() {
    		alert(i);
    	})
    }
    

    似乎很容易理解这段代码,但是实际上,不管点击哪个<li>标签,都会弹出数字5。还不清楚原因的同学,可以先来了解一下html事件处理程序和js作用域的相关知识。

    有个很直接的方法,每次输出li标签对应的innerText即可。如果我一定要输出这个i呢?可以使用闭包的方式:

    for(var i = 1; i < 5; i++){
    	(function(x){
    		document.getElementById('li' + x).addEventListener('click', function(){
    			alert(x)
    		})
    	})(i)
    }
    

    这里形如(function(){})()的代码块,叫做“立即被调用的函数表达式”(Immediately Invoked Function Expression)。可以思考,这里闭包如何产生?

    另外,采用ES6新增的变量类型let,也可以快速的解决该问题。

    for(let i = 1; i < 5; i++){
    	document.getElementById('li' + i).addEventListener('click', function() {
    		alert(i);
    	})
    }
    

    用let代替var来声明变量,就可以把变量的作用域限制在当前代码块中。变量i只存在于for循环中,一旦循环结束,在其他位置均无法访问该变量。

    上面方法都是通过循环,通过addEventListener方法分别给每个<li>标签添加点击事件。这样做完全OK,不会导致什么问题。

    但是在javaScript中,添加到页面上的事件处理程序的数量,将直接关系到页面的整体运行性能。首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差。其次,必须事先制定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。

    想象以上示例中,<li>标签的数量很大时,循环为每个子元素添加事件,绝非好方法。下面给出一种优雅的方法,采用事件委托

    document.getElementById('container').addEventListener('click', function(event) {
    	var target = event.target;
    	if(target.tagName == 'LI'){
    		alert(target.innerText);
    	}
    }, false);
    

    这段代码里,使用事件委托只为<ul>元素添加一个onclick事件处理程序。因为有事件冒泡机制,单击每个<li>标签时,都会被这个函数处理。关于事件流,主要为事件捕获阶段与事件冒泡阶段,可以另行了解。

    参阅学习文档:

    You Don't Know JS — 第三章:作用域与闭包

    ECMAScript 6 入门 — let 和 const 命令

  • 相关阅读:
    SpannaleString总结
    【未完成】bug记录2013427>import工程时出现Build path contains duplicate entry:'src' for project 'XXX'
    【未完成】给eclipse项目改名
    android创建和删除桌面快捷方式
    bug记录2013426(2)>Select at least one project错误
    hosts配置
    获取当前应用的版本号及android系统版本号及手机型号
    转载:如何将offcie 2003文档(.doc、.xls、.ppt)转换成mht文档
    转载:.NET2.0 验证控件常用的正则表达式
    转载: RESTORE DATABASE命令还原SQLServer 2005 数据库
  • 原文地址:https://www.cnblogs.com/aliyuntao/p/7737812.html
Copyright © 2011-2022 走看看