首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 循環綁定點擊事件閉包陷阱:target 變量被覆蓋導致總顯示最後一張圖

     編輯:程式設計綜合問答

問題現象

循環遍歷鏈接數組,為每個 <a> 綁定 onclick 切換圖片,點擊任意鏈接均顯示最後一張圖。

錯誤代碼

var links = document.getElementsByTagName('a');
var target; // 全局變量
for (var i = 0; i < links.length; i++) {
    target = links[i].getAttribute('href'); // 循環中不斷覆蓋
    links[i].onclick = function() {
        document.getElementById('placeholder').src = target; // 閉包捕獲同一變量
        return false;
    };
}

原因分析

JS 只有**函數作用域**,無塊級作用域。循環中 target 是同一個變量,循環結束後值為最後一個 href。所有 onclick 形成的閉包引用的是**同一個** target,故均獲取最終值。

解決方案

方案一:立即調用函數表達式 (IIFE) 創建獨立作用域

for (var i = 0; i < links.length; i++) {
    (function(href) {
        links[i].onclick = function() {
            document.getElementById('placeholder').src = href;
            return false;
        };
    })(links[i].getAttribute('href'));
}

方案二:使用 let 宣告循環變量 (ES6)

for (let i = 0; i < links.length; i++) {
    let href = links[i].getAttribute('href'); // 每次迭代創建新綁定
    links[i].onclick = function() {
        document.getElementById('placeholder').src = href;
        return false;
    };
}

方案三:將數據存儲在 DOM 元素上

for (var i = 0; i < links.length; i++) {
    links[i].dataset.target = links[i].getAttribute('href');
    links[i].onclick = function() {
        document.getElementById('placeholder').src = this.dataset.target;
        return false;
    };
}

總結

循環中綁定事件時,**避免直接引用循環外變量**;採用 IIFE、let 或 DOM 數據屬性將當前值「鎖定」到各自閉包中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved