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

jQuery hover事件在for循环中仅首个元素生效问题求助

问题:循环生成元素后hover事件仅对首个元素生效

通过for循环创建两个玩家相关的div元素,实现鼠标悬停时改变对应统计div的高度,但hover事件仅对第一个生成的元素生效,其他基于ID的jQuery操作均正常。相关代码如下:

var result =[
    2,
    "name:Tom;bc:67;lp:77;fn:37;ic:65;ag:45;sp:56;st:54;pc:66", 
    "name:Thomas;bc:70;lp:44;fn:70;ic:44;ag:60;sp:70;st:30;pc:30"
];

for (var a = 1; a < result[0] + 1; a++){

  var players = result[a].split(";");
  var playername = players[0].split(":");
  var element = document.createElement("div");
  var elementc = document.createElement("div");
  var elements = document.createElement("div");
  
  for (var s = 1; s < 8; s++){
    var ps = document.createElement("p");
    ps.innerHTML = players[s] + "   ";
    elements.appendChild(ps);
  }

  element.id = playername[1];
  elementc.id = playername[1] + "id";
  elements.id = playername[1] + "stats";
  elementc.appendChild(element);
  document.getElementById('manage').appendChild(elementc);
  document.getElementById('manage').appendChild(elements);

  document.getElementById(playername[1] + "id").style.position = "Relative";
  document.getElementById(playername[1] + "id").style.position = "Relative";
  document.getElementById(playername[1] + "id").style.width = "87vw";
  document.getElementById(playername[1] + "id").style.margin = "0.5vw";
  document.getElementById(playername[1] + "id").style.height = "10vw";
  document.getElementById(playername[1] + "id").style.border = "1vw solid cyan";
  document.getElementById(playername[1]).style.position = "Relative";
  document.getElementById(playername[1]).style.cssFloat = "left";
  document.getElementById(playername[1]).style.width = "10vw";
  document.getElementById(playername[1]).style.height = "10vw";
  document.getElementById(playername[1]).style.backgroundImage = "url(Players/" + playername[1] + ".jpg";
  document.getElementById(playername[1]).style.backgroundSize = "cover";
  document.getElementById(playername[1] + "stats").style.position = "Relative";
  document.getElementById(playername[1] + "stats").style.backgroundColor = "lightgrey";
  document.getElementById(playername[1] + "stats").style.overflowY = "scroll";
  document.getElementById(playername[1] + "stats").style.width = "87vw";
  document.getElementById(playername[1] + "stats").style.height = "20";
  
  $("#" + playername[1] + "stats")
    .children().css("background", "linear-gradient(to right,#0D7377 50%, #ffffff 50%)");

  $("#" + playername[1] + "stats")
    .children().css("width", "fit-content");

  $("#" + playername[1] + "stats")
    .children().css("float", "left");

  $("#" + playername[1] + "stats")
    .children().css("margin", "2vw");

  $("#manage").children().css("margin-top", "30vw");
  //The hover here

  $("#" + playername[1] + "id").hover(
    function(){
      $("#" + playername[1] + "stats").animate({'height': '20vw'}, 'slow');
    },
    function(){
      $("#" + playername[1] + "stats").animate({'height': '0vw'}, 'slow');
    }
  );
}

问题原因

核心问题是**var声明的变量作用域特性和闭包的延迟绑定**:

  • 用var声明的playername属于函数级作用域,整个循环中只有一个变量实例。
  • hover事件的回调函数是闭包,不会立即执行,当循环结束后,所有回调引用的playername[1]都是循环最后一次的取值(即Thomas)。
  • 因此无论悬停哪个xxxid元素,最终都会操作Thomasstats这个div,导致视觉上只有第一个元素的hover“生效”(实际是错误触发了最后一个元素的统计框)。

解决方法

方案1:用let替代var声明变量

let具有块级作用域,每次循环会创建新的变量实例,回调函数会绑定当前循环的playername值:

// 修改循环变量和playername的声明方式
for (let a = 1; a < result[0] + 1; a++){
  let players = result[a].split(";");
  let playername = players[0].split(":");
  // 剩余代码保持不变
}

方案2:利用闭包捕获当前变量值

通过立即执行函数(IIFE)创建闭包,保存当前循环的playername值:

// 替换原hover绑定代码
(function(currentName) {
  $("#" + currentName + "id").hover(
    function(){
      $("#" + currentName + "stats").animate({'height': '20vw'}, 'slow');
    },
    function(){
      $("#" + currentName + "stats").animate({'height': '0vw'}, 'slow');
    }
  );
})(playername[1]);

方案3:通过DOM结构关联目标元素(推荐)

利用DOM元素的相邻关系,用jQuery的next()方法直接获取当前xxxid元素后的统计div,无需依赖变量:

// 替换原hover绑定代码
$("#" + playername[1] + "id").hover(
  function(){
    $(this).next().animate({'height': '20vw'}, 'slow');
  },
  function(){
    $(this).next().animate({'height': '0vw'}, 'slow');
  }
);

额外代码修复

  • 初始统计div高度设置错误:document.getElementById(playername[1] + "stats").style.height = "20"; 改为 "0vw",确保初始状态隐藏。
  • 背景图片URL缺少闭合括号:backgroundImage = "url(Players/" + playername[1] + ".jpg" 改为 "url(Players/" + playername[1] + ".jpg)"。

内容的提问来源于stack exchange,提问作者Error 2.0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:11:07