• 利用js输出ul下li的index索引值


    <!DOCTYPE html>
    <html>
    	<head>
    	 	<meta charset="UTF-8">
    	    <title>打印索引</title>
    	</head>
    	<style type="text/css">
    		li{background: pink;margin-bottom: 10px;height: 40px;}
    	</style>
    	<body>
                    <ul>
    		    <li>click</li>
    		    <li>click</li>
    		    <li>click</li>
    		    <li>click</li>
    		    <li>click</li>
    		</ul>
    	</body>
    	<script>
                var nodeList = document.getElementsByTagName('li');
    	    for (var i = 0; i < nodeList.length; i++) {
    	       nodeList[i].addEventListener("click", function(e) {
    	            console.log(i)
    	        }, false);
    	    }
            </script>
    </html> 

      上面代码会和我们预期的结果不应,每次点击输出的都是最后一个元素的索引。
      function(e){}的匿名函数,在执行时,每一个都会创建一个新的作用域。这些匿名函数不会立即执行,仅仅是被定义,只有在点击时才执行,被当做参数传入addEventListener函数。所以在执行时i的值已经变为最后一个索引值。

      要解决这个问题,我们可以用以下几种方案:

    方案1----使用闭包;

    <script>
        var nodeList = document.getElementsByTagName('li');
           for (var i = 0; i < nodeList.length; i++) {
            (function(j){
                nodeList[j].addEventListener("click", function(e) {
                   console.log(j);
                }, false);
            })(i) ;
        }
    </script>

    方案2-----使用es6中let的块级作用域;

    <script>
        var nodeList = document.getElementsByTagName('li');
        for (let i = 0; i < nodeList.length; i++) {
           nodeList[i].addEventListener("click", function(e) {
                console.log(i)
            }, false);
        }
    </script>

    方案3----利用事件委托机制;

      如果li较少的话,利用上面方式实现是可以的,但是如果li的数量过多,为每个li添加事件侦听就会对页面性能产生很大的影响,我们可以采用委托实现。 利用Array.prototype.slice.call(nodeList)的作用是将具有length属性的元素转为数组,这样可利用indexOf方法获取li的索引值。

    <script>
        var nodeList = document.getElementsByTagName('li');
        arrNodes = Array.prototype.slice.call(nodeList);
        nodeUls = document.getElementsByTagName('ul');
        nodeUls[0].addEventListener("click",function(event){
            var event = event || window.event;
            var target = event.target || event.srcElement;
            console.log(arrNodes.indexOf(target))
        },false);
    </script>

    方案4-----使用虚拟属性;

    <script>
        var nodeList = document.getElementsByTagName('li');
        for(var i=0; i< nodeList.length; i++){
            nodeList[i].index = i;
            nodeList[i].addEventListener("click",function(e){
                console.log(this.index)
            },false)
        }
    </script>

    方案5----利用自定义属性;

      ul>li结构中给li标签加上自定义属性

    <ul>
        <li data-index="0">click</li>
        <li data-index="1">click</li>
        <li data-index="2">click</li>
        <li data-index="3">click</li>
        <li data-index="4">click</li>
    </ul>
    

      然后js代码如下

    <script>
        var nodeList = document.getElementsByTagName("li");
        for(var i=0; i<nodeList.length ; i++){
            nodeList[i].addEventListener("click",function(e){
                console.log(e.target.dataset.index);//自定义属性用data-index格式的,可以使用dataset获取;
               console.log(this.getAttribute("data-index"));
            },false)
        }
    </script>
    

      

  • 相关阅读:
    Python数组/切片
    ArcGISEngine 版本升级的方法
    c# 使用类名称访问成员变量
    向模拟器里添加图片的简单方法
    通过self调用propery和直接调用propery的区别
    Objectivec 使用构造函数来初始化函数并调用函数的方法
    IPhone模拟器截取当前活动窗体,并保存为图片
    Windows Server2008 安装Oracle失败
    ALL、DISTINCT、DISTINCTROW、TOP 谓词
    ObjectiveC 语法快速参考
  • 原文地址:https://www.cnblogs.com/wangyongshf/p/7466799.html
Copyright © 2020-2023  润新知