【问题标题】:How do I add an event listener on a Class constructer with jQuery?如何使用 jQuery 在 Class 构造函数上添加事件侦听器?
【发布时间】:2021-09-15 08:29:59
【问题描述】:

当我点击骰子时,我需要改变骰子的 this.value,但现在我只是想让它显示警报,但我什至做不到。我已经深入研究了 e.target 以及几乎所有我能找到的东西,但我只是不知道我错过了什么我觉得这是一个愚蠢的问题,但我现在花了一个多小时试图弄清楚这一点出来了,我拿不到。

function randomNumber(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
const diceArray = [];
const body = document.body;

class Die {
  constructor() {
    this.value = this.roll();
    this.div = $(`<div class="a-die d-flex align-items-center justify-content-center"><h1 class="die-text">${this.value}</h1></div>`);
    diceArray.push(this);
    $('#diceHolder').append(this.div);
    this.div.addEventListener("click", function() {
      alert('hello');
    })
  }
  roll = () => {
    return randomNumber(1, 7);
  }
  refreshView = () => {
    $(this.div).find('h1').text(this.value);
  }
  rollAll = () => {
    $(this.value).replaceWith(randomNumber(1, 7));
  }
}



$('#genDice').on('click', () => {
  let thisDie = new Die()
});
$('#yahtzee').on('click', () => $('.die-text').text(randomNumber(1, 7)));
$('#sumDice').on('click', () => {
  const thing = diceArray.reduce((acc, val) => {
    return acc + val.value;
  }, 0)
  alert(thing);
})

$('#rollDice').on('click', () => diceArray.forEach(val => {
  // console.log(val);
  val.value = randomNumber(1, 7);
  val.refreshView();
}));
$('#remove').on('click', () => {
  $('.a-die').remove()
  $(diceArray).empty();
});
console.log(diceArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex justify-content-around mb-5 mt-2 py-3 bg-light" style="border: 1px solid black;">
  <div id="genDice" class="btn btn-primary">Generate Die</div>
  <div id="rollDice" class="btn btn-secondary">Roll All Die</div>
  <div id="sumDice" class="btn btn-success">Sum All Dice</div>
  <div id="yahtzee" class="btn btn-danger">Yahtzee</div>
  <div id="remove" class="btn btn-dark">Bye-Bye</div>
</div>
<div id="diceHolder" class="d-flex justify-content-evenly"></div>

【问题讨论】:

    标签: javascript jquery oop ecmascript-6


    【解决方案1】:

    这里有多个问题:

    1. this.div 是一个 jQuery 对象,您不能使用 .addEventListener() 来注册点击事件。在 jQuery 对象上使用 jQuery 的 .click() 方法会更好。

    2. refreshView() 试图创建一个 jQuery 对象的 jQuery 对象。虽然这显然可行,但它是多余的,不应该那样做。

    3. 您使用箭头函数的方法定义使用了一种新语法(字段声明),它没有在原型上定义完整的方法 - 它的工作方式不同。虽然它可以在这种特定情况下工作,但我不推荐它,因为它不像常规方法那样可扩展(并且不在原型上),因此对子类化有限制。因此,方法通常应该定义为普通函数,而不是指定为箭头函数。在某些特殊用例中,您希望所有方法都是“绑定”方法,您可能希望像使用的那样使用字段定义,但我只建议您在明确知道为什么这样做的情况下使用该语法并且您出于特定原因利用它。

    4. rollAll() 可能无法正常工作,因为$(this.value) 将执行$(someNumber),这不太可能匹配任何内容。您需要传递一个 Dom 元素、一个 jQuery 对象或一个 CSS 选择器 t0 $(x)

    所以,这是其中包含这些更改的代码:

    class Die {
        constructor() {
            this.value = this.roll();
            this.div = $(`<div class="a-die d-flex align-items-center justify-content-center"><h1 class="die-text">${this.value}</h1></div>`);
            diceArray.push(this);
            $('#diceHolder').append(this.div);
            this.div.click(() => {
                alert('hello');
            });
        }
        roll() {
            return randomNumber(1, 7);
        }
        refreshView() {
            this.div.find('h1').text(this.value);
        }
        rollAll() {
            $(this.value).replaceWith(randomNumber(1, 7));
        }
    }
    

    然后,你可以这样使用它:

    let die = new Die();
    die.refreshView();
    

    而且,您需要确保在页面 DOM 加载到页面之前不会运行此代码,这样您的 jQuery 引用才能针对已加载的 DOM 正常工作。


    rollAll() 方法还有第三个问题。您正在尝试执行$(this.value),但this.value 是一个随机数,它不太可能在$() 中正常工作以实际在您的DOM 中找到一个元素。您需要将选择器或 HTML 元素传递给 $() 才能使用它。

    【讨论】:

    • @Phil - 我根据显示的代码回答,其中根本没有提到 Babel,箭头函数完全不合适。事实上,这个问题被标记为 ES6。如果 OP 想在问题中添加一些 Babel-ness,那么我们将处理它。
    • @Wayne - 我做了一些其他的更正。您确实将 jQuery 对象与常规 HTML 对象混为一谈,而且非常令人困惑。我根本不会这样写代码。请使用所有代码,因为我做了大约 5-10 次不同的更改来修复许多问题。
    • @Phil - 是的,this.div 已经是一个 jQuery 对象,所以我只是更改为 this.div.click()。这段代码是连续问题的剥皮洋葱。
    • 我刚刚检查了箭头函数方法,显然它确实工作。直到~jsfiddle.net/uheto1q8
    • @Wayne - 显然您使用的箭头函数构造在某些情况下确实有效。但是,我不建议使用它。只是很复杂。方法应该是普通函数,以便它们从调用它们的对象继承this 值。此外,我展示的语法更易于编写和理解。
    猜你喜欢
    • 2012-09-25
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    相关资源
    最近更新 更多