HTML+JS开发国际象棋:appendChild创建元素后无法选中该元素
问题原因
你在页面初始化阶段仅给当时已存在的所有<img>元素绑定了select点击事件,后续通过createElement动态生成的新棋子图片没有绑定该事件,因此无法触发选中逻辑。同时你现有代码还有个遗留问题:移动棋子后原位置的旧棋子没有删除,会出现同一个棋子同时存在两个位置的情况,需要一并修复。
修复方案
方案1:动态创建元素时手动绑定事件
修改move函数,给新创建的img添加和原有棋子一致的属性、绑定点击事件,同时删除原位置的旧棋子:
function move() { if (selector == "") { return; } var initial_img = document.getElementById(selector); var img = document.createElement("img"); // 复制原有棋子的类名、id,保证功能一致 img.className = initial_img.className; img.id = initial_img.id; img.src = initial_img.src; // 给新生成的图片绑定点击事件 img.onclick = select; this.appendChild(img); // 删除原位置的旧棋子 initial_img.remove(); document.getElementById(selector).style.backgroundColor = "transparent"; selector = ""; // 更新可点击的空棋盘格列表,避免已有棋子的格子仍触发移动逻辑 squares = Array.from(document.querySelectorAll("p")).filter(item => !item.querySelector(".icon")); for (let square of squares) { square.onclick = move; } }
方案2:使用事件委托(更推荐)
直接把点击事件绑定在所有棋子的共同父元素上,不管是原有还是新增的棋子都能自动触发事件,不需要每次单独绑定,逻辑更简洁:
var selector = ""; // 直接给棋盘父元素绑定事件,覆盖所有子元素点击 document.getElementById('board').addEventListener('click', function(e) { // 点击的是棋子图片时触发选中逻辑 if(e.target.classList.contains('icon')) { select.call(e.target); } // 点击的是空棋盘格时触发移动逻辑 else if(e.target.tagName === 'P' && !e.target.querySelector('.icon')) { move.call(e.target); } }) function select() { if (selector != "") { document.getElementById(selector).style.backgroundColor = "transparent"; } selector = this.id; document.getElementById(selector).style.backgroundColor = "rgba(75, 137, 78, 0.5)"; } var squares = Array.from(document.querySelectorAll("p")).filter(item => !item.querySelector(".icon")); function move() { if (selector == "") { return; } var initial_img = document.getElementById(selector); var img = document.createElement("img"); img.className = initial_img.className; img.id = initial_img.id; img.src = initial_img.src; this.appendChild(img); initial_img.remove(); document.getElementById(selector).style.backgroundColor = "transparent"; selector = ""; }
内容的提问来源于stack exchange,提问作者MWD
相关产品推荐
相关产品推荐

