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

JavaScript DOM读取值与UI显示不同步问题咨询

问题根因

  • 你拿到的this.attributes是DOM提供的实时NamedNodeMap引用集合,不是静态快照。只要DOM元素的属性发生修改,这个集合里的内容会自动同步最新值,哪怕你是在修改操作前就完成了遍历。
  • 浏览器控制台对引用类型的打印存在懒求值特性:你在控制台点击展开打印的attr对象时,浏览器才会读取该对象的当前值,此时你后面的if分支修改属性的代码已经执行完成,自然看到的是修改后的text-decoration: line-through;。你添加的alert()只会阻塞代码执行,不会改变引用指向,关闭alert后代码会继续执行修改属性,最终控制台展示的还是更新后的值。

解决方案

要拿到点击触发瞬间的属性静态值,只需要打印基础类型的属性值,或者提前把属性内容做静态快照即可,修改后的代码参考:

var theLi = document.getElementById("here");
theLi.addEventListener("click", crossOff);
theLi.setAttribute("style", "color:red;");
theLi.setAttribute("crossed", "off");

function crossOff(element) {
  var isOn = this.getAttribute("crossed") == "on";
  // 方式1:直接打印属性的基础类型值,输出的就是执行到此处的快照值
  console.log('当前style值:', this.getAttribute('style'));
  console.log('当前crossed值:', this.getAttribute('crossed'));

  // 如果你要遍历所有属性,可以取静态值打印
  var attrs = this.attributes;
  for (const attr of attrs) {
    // 打印name和value两个基础类型值,不会后续变更
    console.log(attr.name, attr.value);
  }

  alert("huh??");

  if (isOn) {
    this.setAttribute("style", "text-decoration: none;");
    this.setAttribute("crossed", "off");
  } else {
    this.setAttribute("style", "text-decoration: line-through;");
    this.setAttribute("crossed", "on");
  }
}

如果你确实需要打印完整的属性对象快照,可以把实时对象转成普通静态对象再打印:

for (const attr of attrs) {
  console.log(Object.assign({}, attr));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:24:00