有时候,我们需要点击标签的时候,知道当前的索引值。这样好利用索引值去获取另一个标签,进行样式更改。
最典型的运用就是图片轮播。比如这种:
点击对应点,就要显示对应的图片和文字内容。 如何把点 跟 图片及文字 对应起来呢? 靠的就是索引。
有如下结构:
<ul id="myul">
<li>你好1</li>
<li>你好2</li>
<li>你好3</li>
<li>你好4</li>
<li>你好5</li>
</ul>
我想点击任意 li,就输出它的索引值。
方法有几个:
方法一:最简单的就是 jQuery方式了。
$("#myul>li").on("click",function(){
var $this = $(this); // 习惯性保存下当前标签
var index = $this.index();
console.info( index );
});
方法二:原生态JS。写标签的时候,给 li 添加自定义属性 index 。点击 li 的是时候,就获取 当前标签 的 自定义属性 index。
改造 HTML 结构如下:(索引不出意外的话,都是 0 开始的。)
<ul id="myul">
<li index="0">你好1</li>
<li index="1">你好2</li>
<li index="2">你好3</li>
<li index="3">你好4</li>
<li index="4">你好5</li>
</ul>
var myul = document.getElementById("myul");
var li = myul.children;
for( var i = 0 ; i<= li.length-1 ; i++){
li[i].onclick = function(){
var _this = this;
var index = _this.getAttribute("index");
console.info( index);
}
}
方法三:原生态JS。方法二尽管可以完成要求,但是如果标签数量经常变动,也不是个好事情,还要改自定义属性。所以,还是用原来的结构:
<ul id="myul">
<li>你好1</li>
<li>你好2</li>
<li>你好3</li>
<li>你好4</li>
<li>你好5</li>
</ul>
var myul = document.getElementById("myul");
var li = myul.children;
for( var i = 0 ; i<= li.length-1 ; i++){
li[i].index = i ; // 添加属性
li[i].onclick = function(){
var _this = this;
console.info( _this.index); // 输出自定义属性
}
}
li[i].index = i ; 这句代码,其实还是在给 li 标签添加 属性 index。 标签属性也可以这样加? 当然~!因为标签本质就是一个对象,是一个对象,当然可以添加属性了。不过这属性是JS 赋予它的,没有直接写在标签上,所以不能使用 getAttribute() 获取它的值。
方法四:原生态JS,利用闭包。
var myul = document.getElementById("myul");
var li = myul.children;
for( var i = 0 ; i<= li.length-1 ; i++){
li[i].onclick=(function(n){
console.info(n); // 这个代码会直接执行哦。它在闭包里。
return function(){
console.info( n );
}
})(i);
}
原理:li 创建事件函数的时候,其实执行了一个闭包。这个闭包把 对应的 i 作为参数传进来,并赋值给 闭包的内部函数。内部函数会保持这个 i 值不变。这样,点击任意一个 i ,就会得到对应的索引 i。
方法五:原生态JS,还是利用闭包。
var myul = document.getElementById("myul");
var li = myul.children;
for( var i = 0 ; i<= li.length-1 ; i++){
(function(n){
li[n].onclick=function(){
console.info(n);
}
})(i);
}
每次执行循环,执行闭包,闭包可以保留当前 i 的值到 内部中。
方法四,与方法五,都是避免了直接在for循环里输出 i 的值(怎么输出都是 4),而是借用了闭包保留当前 i 的值。
方法六:还是ES6爽快,用 let 定义 循环变量 i 就ok了。鉴于此,大家还是及早掌握 ES6 吧。
let myul = document.getElementById("myul");
let li = myul.children;
for( let i = 0 ; i<= li.length-1 ; i++){
li[i].onclick = function(){
console.info( i );
}
}
原因,let 定义 i, 会把每次循环都成一个封闭空间。 i 值 就不会传递到空间外了(虽然它也可以自增)。具体可以了解下ES6 对for 的解释。