frankenapps frankenapps - 7 months ago 6
Javascript Question

JQuery: Are there any downsides of using only one listener for all buttons?

I am currently working on a jquery implementation of tictactoe in order to learn jquery. In my html I defined nine buttons like this:

<div class="container">
<div class="column-center"><button id="1" style="width: 100px; height: 100px"></button></div>
<div class="column-left"><button id="2" style="width: 100px; height: 100px"></button></div>
<div class="column-right"><button id="3" style="width: 100px; height: 100px"></button></div>
</div>
<div class="container">
<div class="column-center"><button id="4" style="width: 100px; height: 100px"></button></div>
<div class="column-left"><button id="5" style="width: 100px; height: 100px"></button></div>
<div class="column-right"><button id="6" style="width: 100px; height: 100px"></button></div>
</div>
<div class="container">
<div class="column-center"><button id="7" style="width: 100px; height: 100px"></button></div>
<div class="column-left"><button id="8" style="width: 100px; height: 100px"></button></div>
<div class="column-right"><button id="9" style="width: 100px; height: 100px"></button></div>
</div>


When implementing the jquery logic i thought it would be nice if I would only use one listener for all those buttons, because they are all doing the same thing, I did it like that:

$("button").on('click', function () {
if(this.id==1||this.id==2||this.id==3||this.id==4||this.id==5||this.id==6||this.id==7||this.id==8||this.id==9){
$("#"+String(this.id)).css("background-color",$("#color1").css('backgroundColor'));
$("#"+String(this.id)).prop('disabled', true);
//all the other logic here...
}
else if (this.id==startGame) {
//start the Game
}
});


I have three questions here:


  1. What about performance is it worse than using one listener for every button?

  2. Is it good practice do implement the listener like that?

  3. Are there any downsides (e.g. some weird bugs that could happen)?


Answer

What about performance is it worse than using one listener for every button?

No.

Is it good practice do implement the listener like that?

It's fine, though I would separate out the number buttons from the other as they're really unrelated. Delegation might be better for the number buttons, and there are details in your implementation you could probably improve, but the overall concept is fine.

Are there any downsides (e.g. some weird bugs that could happen)?

No more so than with anything else.


For instance, I'd probably look at it like this (assumes a container around the game that doesn't have the "Start game" button in it):

// Delegation for the number buttons
$("#container-for-the-game").on("click", "button", function () {
    $(this).css("background-color", $("#color1").css('backgroundColor'))
           .prop('disabled', true);
    //all the other logic here...
});
// Start game separately, as it's unrelated
$("#startGame").on("click", function() {
    //start the Game
});

There's an important change above, which is that I switch from

$("#"+String(this.id))

to

$(this)

Notes about that:

  • id values are already strings, no need to use String(...) on it.

  • You'll get people telling you you can't use id values that are all digits. You can, it's perfectly fine, but note the next bullet point.

  • Technically, #1 and such are invalid CSS selectors. jQuery tolerates them provided they're on their own like that (as a by-product of optimizing to a getElementById call instead of querySelectorAll), but a CSS ID selector cannot start with an unescaped digit. While $("#1") works (with the current jQuery), $("#1 span") wouldn't (to find a span as a descendant of the element with the id "1"). Best to avoid the habit.

  • this is already the button that was clicked, so there's no need for a DOM lookup.

  • Unless you're using those id values for something else (I suspect you probably are), you don't need them.