You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript addEventListener异常:mouseenter事件始终返回数组最后一项

循环绑定mouseenter事件时获取到的总是数组最后一项的问题

我在使用JavaScript的addEventListener绑定mouseenter事件时遇到问题。原本计划实现当产品图片数组长度大于1时,鼠标悬停在预览图上切换显示其他图片,但目前在循环内绑定的mouseenter事件触发时,始终返回数组的最后一项,而非当前选中项。

原代码

var product_type = "";
for(let i = 0; i < this.products_list.length; i++){
    var row = this.products_list[i], self = this;
    if(row.product_type != product_type){
        product_type = row.product_type;  
        var sub_title = document.createElement("h2"),
            separator = document.createElement("hr"),
            display_list = document.createElement("ul");
            sub_title.id = product_type;
            sub_title.innerHTML = localeString.get(product_type);
            display_list.id = product_type+"-list";

            this.catalog.appendChild(sub_title);
            this.catalog.appendChild(separator);
            this.catalog.appendChild(display_list);     
    }
    var product = document.createElement("li"),
        preview = document.createElement("img"),
        container = document.createElement("div");
    var array_images = row.product_images.split(",");

        preview.src = this.assets+product_type+"/"+array_images[0]+".jpg";
        preview.alt = product_type+"#"+row.product_id;
        
        container.appendChild(preview);
        product.appendChild(container);

        preview.addEventListener("mouseenter", event => {
            console.log(array_images);
            // 这里总是输出数组的最后一项,而非当前选中项
        });

        display_list.appendChild(product);
}

问题原因

你用var声明了array_images,var是函数作用域,循环里每次赋值都会覆盖同一个变量。事件回调是异步触发的,等回调执行时,循环已经跑完,array_images早已经被最后一次循环的赋值覆盖,所以所有回调都指向最后那个数组。

解决方法

方法1:把var array_images改成let

利用let的块级作用域特性,每次循环都会创建一个独立的array_images变量,回调里引用的就是当前循环对应的数组:

// 把var改成let
let array_images = row.product_images.split(",");

方法2:用立即执行函数隔离作用域

把事件绑定逻辑包裹在立即执行函数里,将当前的array_images作为参数传入,形成独立作用域:

var array_images = row.product_images.split(",");

// ... 其他代码

(function(currentImages) {
  preview.addEventListener("mouseenter", event => {
    console.log(currentImages);
  });
})(array_images);

方法3:把数组存在元素自定义属性里

将array_images转成字符串存在预览图的dataset属性中,触发事件时再解析出来:

var array_images = row.product_images.split(",");
// 存自定义属性时转成JSON字符串
preview.dataset.productImages = JSON.stringify(array_images);

preview.addEventListener("mouseenter", event => {
  // 触发时解析字符串得到原数组
  const currentImages = JSON.parse(event.target.dataset.productImages);
  console.log(currentImages);
});

内容的提问来源于stack exchange,提问作者W.DavidC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:40:35