Reputation: 765
I need the dice's this.value to change when I click on the dice, but right now I'm just trying to get it to display an alert but I can't even do that. I have looked deep into e.target and just about everything I can find, but I just don't know what I'm missing I feel like this is a silly question, but I've spent over an hour now trying to figure this out and I can't get it.
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>
Upvotes: 0
Views: 61
Reputation: 707476
There were multiple problems here:
this.div
is a jQuery object that you can't use .addEventListener()
on to register for the click event. Much better to just use jQuery's .click()
method on the jQuery object.
refreshView()
was trying to make a jQuery object of a jQuery object. While apparently that can work, it's redundant and shouldn't be done that way.
Your method definition using arrow functions was using a newish syntax (field declarations) that does not define full-fledged methods on the prototype - it works differently. While it can be made to work in this specific case, I would not recommended it because it's not as extensible as regular methods (and not on the prototype) and thus has limitations with subclassing. So, methods should generally be defined as normal functions, not assigned as arrow functions. There are some special use cases where you want all your methods to be "bound" methods that you may want to use field definitions like you were using, but I would only recommend using that syntax if you specifically know why you're doing it and you're leveraging that for a specific reason.
rollAll()
probably does not work as shown because $(this.value)
will be doing $(someNumber)
which is unlikely to match anything. You need to pass a Dom Element, a jQuery object or a CSS selector t0 $(x)
.
So, here's the code with those changes in it:
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));
}
}
Then, you can use it like this:
let die = new Die();
die.refreshView();
And, you need to make sure that this code does not run before the page DOM is loaded into the page so that your jQuery references will work properly against the already loaded DOM.
There's a third problem with the rollAll()
method. You're trying to do $(this.value)
, but this.value
is a random number which is unlikely to work properly in $()
to actually find an element in your DOM. You need to pass a selector or an HTML element to $()
in order to use it.
Upvotes: 2