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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:04:45