国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JS常見問題之為什么點(diǎn)擊彈出的i總是最后一個(gè)

2019-11-20 10:51:40
字體:
供稿:網(wǎng)友

在前端群里看見過很多人問過這個(gè)問題,今晚又有人問了這個(gè)問題,所以寫篇文章整理一下。首先看一下代碼,點(diǎn)擊li之后彈出當(dāng)前l(fā)i所對應(yīng)的索引值。于是很多人刷刷刷寫出了下面的代碼。

var aLi = document.getElementsByTagName('li');for(var i = 0; i < aLi.length; i++){  aLi[i].onclick = function(){    alert(i);  }}

  但是結(jié)果不盡人意,為了簡單,我們約定一下頁面中有2個(gè)li。點(diǎn)擊li之后彈出的都是2。
  我們首先來分析一下為什么結(jié)果是1.我們可以簡單的將循環(huán)分成兩部。

i = 0時(shí),aLi[0].onclick = function(){alert(i)}i = 1時(shí),aLi[1].onclick = function(){alert(i)}i = 2時(shí),不滿足條件跳出循環(huán).

 在執(zhí)行click的函數(shù)的時(shí)候,會有一個(gè)作用域鏈,這個(gè)作用域鏈?zhǔn)且粋€(gè)對象列表,這組對象定義了代碼作用域中的變量。( 關(guān)于變量對象的內(nèi)容想更詳細(xì)了解的可以查看變量對象。)當(dāng)我們alert(i)的時(shí)候,會去從內(nèi)到外的去尋找變量i。這個(gè)時(shí)候這個(gè)函數(shù)的作用域鏈上有兩個(gè)對象,這時(shí)循環(huán)已經(jīng)結(jié)束了,i此時(shí)的值為2.所以點(diǎn)擊任何一個(gè)li,彈出的都是2,而不是我們想要的索引值。重點(diǎn)在于彈出的是變量i,變量i,變量i。重要的事情說三遍。

 那么問題來了,我們要如何解決這個(gè)問題呢。我們需要做的就是在每次給aLi[i]綁定事件的時(shí)候,將這個(gè)時(shí)候i的值保存在內(nèi)部的作用域中。解決方案如下。

var aLi = document.getElementsByTagName('li');for (var i = 0; i < aLi.length; i++) { (function(i){   aLi[i].onclick = function () {      alert(i);     }; })(i)}

這里涉及到一個(gè)塊級作用域的概念。在es6出來前,函數(shù)是作為創(chuàng)建塊級作用域的主要手段。這里我們通過在aLi[i].onclick外面套上一層函數(shù),將i作為參數(shù),我們重新分析一下結(jié)果。

 i = 0時(shí),  (function(i){   aLi[0].onclick = function(){     alert(i);   }  })(0)  i = 1時(shí),  (function(i){   aLi[1].onclick = function(){     alert(i);   }  })(1)  i = 2時(shí),不滿足條件跳出循環(huán).

由于多了一層自執(zhí)行函數(shù)的包裹,當(dāng)我們點(diǎn)擊li時(shí),會有三層的作用域,從內(nèi)帶外分別是:click函數(shù)內(nèi)部的變量對象,自執(zhí)行函數(shù)的變量對象和最外層的window對象。查找到第二層的時(shí)候,找到了i,自執(zhí)行函數(shù)的i等于傳入的參數(shù)值,相對應(yīng)的存下了當(dāng)時(shí)i的值,所以就彈出了相應(yīng)的索引值。

下面再給大家分享一個(gè)js常見的問題,實(shí)現(xiàn)點(diǎn)擊li能夠彈出當(dāng)前l(fā)i索引與innerHTML的函數(shù)

點(diǎn)擊其中一項(xiàng)需要alert出如下結(jié)果:

按照我們平常的想法,代碼應(yīng)該是這樣寫的:

var myul = document.getElementsByTagName("ul")[0];  var list = myul.getElementsByTagName("li");   function foo(){    for(var i = 0, len = list.length; i < len; i++){      list[i].onclick = function(){        alert(i + "----" + this.innerHTML);      }    }  }  foo();

但是不巧的是產(chǎn)生的結(jié)果是這樣的: 


索引index為什么總是4呢,這是js中沒有塊級作用域?qū)е碌摹_@里有三種解決思路

1. 使用閉包

<script type="text/javascript">var myul = document.getElementsByTagName("ul")[0];var list = myul.getElementsByTagName("li");function foo(){  for(var i = 0, len = list.length; i < len; i++){    var that = list[i];    list[i].onclick = (function(k){      var info = that.innerHTML;      return function(){        alert(k + "----" + info);      };    })(i);  }}foo();</script>

2.使用ES6中的新特性let來聲明變量

用let來聲明的變量將具有塊級作用域,很明顯可以達(dá)到要求,不過需要注意的是得加個(gè)'use strict'(使用嚴(yán)格模式)才會生效

<script type="text/javascript">var myul = document.getElementsByTagName("ul")[0];var list = myul.getElementsByTagName("li");function foo(){'use strict'  for(let i = 0, len = list.length; i < len; i++){    list[i].onclick = function(){      alert(i + "----" + this.innerHTML);    }  }}foo();</script>

3.引入jquery,使用其中的on或delegate進(jìn)行事件綁定(它們都有事件代理的特性)

<script type="text/javascript" src="jquery-1.8.2.min.js"></script><script type="text/javascript">$("ul").delegate("li", "click", function(){  var index = $(this).index();  var info = $(this).html();  alert(index + "----" + info);});</script><script type="text/javascript">$("ul").on("click", "li", function(){  var index = $(this).index();  var info = $(this).html();  alert(index + "----" + info);});</script>
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 高雄县| 进贤县| 汕头市| 扬州市| 抚远县| 来宾市| 兴山县| 光山县| 晋州市| 上饶市| 甘泉县| 多伦县| 和政县| 南通市| 霍山县| 彭阳县| 石楼县| 酒泉市| 黄冈市| 临朐县| 隆回县| 望谟县| 上饶市| 娱乐| 双鸭山市| 余干县| 蓬溪县| 桐柏县| 靖西县| 额敏县| 福清市| 承德市| 荣成市| 芮城县| 龙山县| 丽水市| 吉安市| 府谷县| 利川市| 大石桥市| 陇川县|