• 给列表元素添加点击事件


    如下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 命令

  • 相关阅读:
    合唱队形2 洛谷U5874
    AC日记——石子归并 codevs 1048
    AC日记——舒适的路线 codevs 1001 (并查集+乱搞)
    AC日记——导弹拦截 洛谷 P1020 (dp+模拟)
    常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)
    AC日记——信息传递 洛谷 P2661 (tarjan求环)
    AC日记——逃出克隆岛 (bfs)
    数字对 (长乐一中模拟赛day2T2)
    改造二叉树 (长乐一中模拟赛day2T1)
    AC日记——热浪 codevs 1557 (最短路模板题)
  • 原文地址:https://www.cnblogs.com/aliyuntao/p/7737812.html
Copyright © 2020-2023  润新知