最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS常見問題之為什么點擊彈出的i總是最后一個

 更新時間:2016年01月05日 10:32:43   投稿:mrr  
最近有很多朋友問我,為什么點擊彈出的i總是最后一個,于是抽時間寫了這篇文章,特此分享到腳本之家平臺,供大家參考

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

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

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

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

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

 那么問題來了,我們要如何解決這個問題呢。我們需要做的就是在每次給aLi[i]綁定事件的時候,將這個時候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)
}

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

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

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

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

點擊其中一項需要alert出如下結果:

按照我們平常的想法,代碼應該是這樣寫的:

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)生的結果是這樣的: 


索引index為什么總是4呢,這是js中沒有塊級作用域導致的。這里有三種解決思路

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來聲明的變量將具有塊級作用域,很明顯可以達到要求,不過需要注意的是得加個'use strict'(使用嚴格模式)才會生效

<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進行事件綁定(它們都有事件代理的特性)

<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>

相關文章

  • 讓FireFox支持innerText的實現(xiàn)代碼

    讓FireFox支持innerText的實現(xiàn)代碼

    DHTML非標準屬性innerText在FireFox中的使用
    2009-12-12
  • JS中獲取函數(shù)調(diào)用鏈所有參數(shù)的方法

    JS中獲取函數(shù)調(diào)用鏈所有參數(shù)的方法

    這篇文章主要介紹了JS中獲取函數(shù)調(diào)用鏈所有參數(shù)的方法,本文直接給出代碼示例,需要的朋友可以參考下
    2015-05-05
  • 使用JavaScript為一張圖片設置備選路徑的方法

    使用JavaScript為一張圖片設置備選路徑的方法

    在做網(wǎng)頁開發(fā)的時候,有時候希望給圖片設置一個備選路徑,即,當src屬性對應的主路徑加載失敗的時候,圖片可以馬上切換到備選路徑,怎么實現(xiàn)呢?下面通過本文給大家分享JavaScript為一張圖片設置備選路徑的方法,一起看看吧
    2017-01-01
  • 使用JS實現(xiàn)圖片展示瀑布流效果(簡單實例)

    使用JS實現(xiàn)圖片展示瀑布流效果(簡單實例)

    下面小編就為大家?guī)硪黄褂肑S實現(xiàn)圖片展示瀑布流效果(簡單實例)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • JS 事件機制完整示例分析

    JS 事件機制完整示例分析

    這篇文章主要介紹了JS 事件機制,結合完整實例形式分析了JavaScript事件響應機制、原理與使用技巧,需要的朋友可以參考下
    2020-01-01
  • js頁面跳轉的常用方法整理

    js頁面跳轉的常用方法整理

    跳轉頁面的方法有很多,在本文整理了一些比較常用,并有示例代碼,感興趣的朋友可以參考下
    2013-10-10
  • 讓編輯器支持word復制黏貼、截屏的js代碼

    讓編輯器支持word復制黏貼、截屏的js代碼

    這篇文章主要為大家詳細介紹了讓編輯器支持word復制黏貼、截屏的js代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • 利用Javascript實現(xiàn)簡單的轉盤抽獎

    利用Javascript實現(xiàn)簡單的轉盤抽獎

    這篇文章主要介紹了利用Javascript實現(xiàn)的簡單的轉盤抽獎,文中分享了兩種抽獎效果,一種是默認轉動,一種是需要點擊開始轉動的,并給出了晚上的示例代碼,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 純JS代碼實現(xiàn)一鍵分享功能

    純JS代碼實現(xiàn)一鍵分享功能

    在qq空間,新浪微博,人人網(wǎng)等網(wǎng)絡平臺大家經(jīng)??梢钥吹揭绘I分享功能,那么基于js代碼是如何實現(xiàn)一鍵分享的呢?下面腳本之家小編給大家介紹js實現(xiàn)一鍵分享功能的代碼,需要的朋友參考下吧
    2016-04-04
  • js最實用string(字符串)類型的使用及截取與拼接詳解

    js最實用string(字符串)類型的使用及截取與拼接詳解

    這篇文章主要介紹了js string使用截取與拼接,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04

最新評論

土默特左旗| 高雄县| 察雅县| 怀仁县| 保康县| 辽宁省| 章丘市| 安福县| 海门市| 丹巴县| 城步| 黄浦区| 双峰县| 崇信县| 明溪县| 瑞丽市| 邳州市| 饶阳县| 长宁区| 宿松县| 阜宁县| 辽源市| 平陆县| 南充市| 奉节县| 安乡县| 舒兰市| 奈曼旗| 高阳县| 荔波县| 庄浪县| 江陵县| 侯马市| 南岸区| 黎川县| 诸城市| 教育| 青川县| 辽中县| 西林县| 祥云县|