如何在两个DOM元素间交换指定子集属性?
解决元素特定属性交换失败的问题
你的代码问题出在保存了Attr对象的引用,而非属性的静态键值对。当你修改元素属性时,保存的Attr对象的value会同步更新,导致最终交换逻辑失效——相当于把修改后的属性又写回了原元素,等于没交换。
修正方案:保存属性的键值对副本
我们需要先把要交换的属性提取为独立的键值对对象(静态副本),再互相赋值给对方元素。这里可以结合你提到的解构赋值简化变量交换,或者直接完成属性赋值:
let elem1 = document.getElementById("item1"); let elem2 = document.getElementById("item2"); let before = document.getElementById("before"); let after = document.getElementById("after"); before.innerHTML = 'before: ' + showData(elem1,elem2); swapAttributes(elem1,elem2); after.innerHTML = 'after: ' + showData(elem1,elem2); function showData(a,b) { let data1 = a.dataset; let data2 = b.dataset; return data1.keepRow + "," + data1.keepCol + " and " + data2.keepRow + "," + data2.keepCol; } function swapAttributes(el1, el2) { // 提取元素中需要交换的属性为键值对 const extractKeepAttrs = (el) => { const attrs = {}; [...el.attributes].forEach(attr => { if (attr.nodeName.startsWith("data-keep-")) { attrs[attr.name] = attr.value; } }); return attrs; }; const el1Attrs = extractKeepAttrs(el1); const el2Attrs = extractKeepAttrs(el2); // 先清空原元素的目标属性,再赋值对方的属性 // 清空el1的data-keep-*属性 Object.keys(el1Attrs).forEach(key => el1.removeAttribute(key)); // 给el1设置el2的属性 Object.entries(el2Attrs).forEach(([key, value]) => el1.setAttribute(key, value)); // 同理处理el2 Object.keys(el2Attrs).forEach(key => el2.removeAttribute(key)); Object.entries(el1Attrs).forEach(([key, value]) => el2.setAttribute(key, value)); }
<div id="item1" data-keep-row=1 data-keep-col=1>item1</div> <div id="item2" data-keep-row=2 data-keep-col=2>item2</div> <p id="before"></p> <p id="after"></p>
解构赋值的应用
如果你想用解构赋值简化变量交换逻辑,可以在提取属性后先交换两个变量,再分别赋值给元素:
// 在swapAttributes函数中,提取属性后: [el1Attrs, el2Attrs] = [el2Attrs, el1Attrs]; // 然后将交换后的属性赋值给对应元素 Object.keys(el1Attrs).forEach(key => el1.removeAttribute(key)); Object.entries(el1Attrs).forEach(([key, value]) => el1.setAttribute(key, value)); Object.keys(el2Attrs).forEach(key => el2.removeAttribute(key)); Object.entries(el2Attrs).forEach(([key, value]) => el2.setAttribute(key, value));
这里的解构赋值只是交换了两个存储属性的对象变量,核心还是用静态的键值对副本避免引用同步问题。
内容的提问来源于stack exchange,提问作者quilkin
相关产品推荐
相关产品推荐

