jQuery类构造函数中如何仅移除被双击的同class div?
我来帮你搞定这个问题!你遇到的核心问题是每次创建Die实例时,都给页面上所有的.div元素重复绑定了点击/双击事件,导致双击单个div时,多个实例的删除方法被触发,进而删掉了多个div。不用给每个div分配ID也能解决,下面是具体的方案和修正后的代码:
1. 只给当前实例的div绑定事件
你之前的代码里用$('.div').dblclick(...),这会把事件绑定到**当前页面所有存在的.div**上——每创建一个新的Die实例,就给所有已存在的div多绑一次事件。正确的做法是只给当前实例刚创建的this.div绑定事件:
class Die { constructor(value) { this.value = value; // 创建当前实例专属的div this.div = $('<div></div>').attr("class", "div"); $(this.div).append(this.value); $('.container').append(this.div); // 只给当前实例的div绑定点击/双击事件 $(this.div).click(() => this.rollOne()); $(this.div).dblclick(() => this.removeOne()); } // 重新掷当前实例的骰子 rollAll() { this.value = Math.floor(Math.random() * 6 + 1); $(this.div).html(this.value); } // 重新掷被点击的当前实例骰子 rollOne() { this.value = Math.floor(Math.random() * 6 + 1); $(this.div).html(this.value); } // 删除当前实例对应的div removeOne() { $(this.div).remove(); } }
这样修改后,每个div只会绑定自己对应的Die实例方法,双击某个div时,只会触发该实例的removeOne,只会删除当前div,不会影响其他骰子。
2. 顺便修复Roll All Dice的事件绑定问题
你当前的代码还有个小bug:每次创建Die实例时,都会给#all按钮绑定一次rollAll事件。比如创建3个实例后,点击Roll All会执行3次rollAll(每个实例各一次),虽然结果看起来是对的,但这种重复绑定的方式很不规范。我们可以用一个数组存储所有Die实例,然后给#all只绑定一次事件:
// 用数组保存所有创建的Die实例 const diceCollection = []; class Die { constructor(value) { this.value = value; this.div = $('<div></div>').attr("class", "div"); $(this.div).append(this.value); $('.container').append(this.div); $(this.div).click(() => this.rollOne()); $(this.div).dblclick(() => this.removeOne()); // 将当前实例加入数组 diceCollection.push(this); } rollAll() { this.value = Math.floor(Math.random() * 6 + 1); $(this.div).html(this.value); } rollOne() { this.value = Math.floor(Math.random() * 6 + 1); $(this.div).html(this.value); } removeOne() { // 删除时顺便从数组里移除当前实例 const index = diceCollection.indexOf(this); if (index !== -1) diceCollection.splice(index, 1); $(this.div).remove(); } } // 只给Roll All按钮绑定一次事件 $('#all').click(() => { diceCollection.forEach(die => die.rollAll()); });
这样点击Roll All时,会遍历所有Die实例,每个实例只执行一次rollAll,逻辑更清晰,也避免了重复绑定的问题。
3. 为什么之前的代码会删多个div?
再给你理清楚根源:当你创建第一个Die实例时,$('.div')只会选中刚创建的那个div,绑定一次双击事件;创建第二个实例时,$('.div')会选中前两个div,给它们各多绑一次双击事件……以此类推。当你双击某个div时,它身上绑定的所有事件都会触发——每个事件对应一个Die实例的removeOne方法,每个方法会删除自己的this.div,所以看起来就是删掉了多个div。
关于this指向的补充
你提到用箭头函数导致this指向异常,其实在这个场景下,箭头函数让this指向Die实例是正确的——因为我们需要在rollOne和removeOne里访问实例的this.div和this.value。如果换成普通函数,this会指向被点击的DOM元素,这时候你就得把Die实例绑定到div的data属性上才能获取,反而更麻烦,所以箭头函数的方案在这里是合适的,只要确保事件只绑定到当前实例的div上就没问题。
内容的提问来源于stack exchange,提问作者cDub

