3

I am learning the basics of jQuery and was testing out what I knew, I tried adding 1 to the text of a DOM element (<span>) that stores a number. The number in the <span> is increased by 1 successfully, however I feel that the way I am updating the element isn't the best way as it seems that I need to call the same jQuery function twice (see code below).

Would anyone be able to suggest a better practice?

HTML

<button onclick="foo('a')">
    <span id="a">0</span> liked this
</button>

JS(jQuery)

function foo(elementId){
    $('#' + elementId).text(parseInt($('#' + elementId).text()) + 1);
}

Thank you :-)

koder613
  • 1,486
  • 5
  • 21

3 Answers3

3

Avoid inline event handlers is the first thing to do. The once you setup your event handler you can reference the element via this:

$('button').click(function() {
  $(this).find('span').text( parseInt($(this).find('span').text()) + 1 );
})
j08691
  • 204,283
  • 31
  • 260
  • 272
  • Thank you. Why should inline event handlers be avoided? – koder613 Sep 17 '20 at 16:42
  • @koder613 I'm glad you asked. See https://stackoverflow.com/questions/15792498/is-it-bad-practice-to-use-inline-event-handlers-in-html and https://stackoverflow.com/questions/5871640/why-is-using-onclick-in-html-a-bad-practice – j08691 Sep 17 '20 at 16:44
2

The way you do it is kind of ok but I would try to avoid storing state in a text node.

There are couple of ways, I'm going to suggest jQuery's .data.

<button onclick="handleClick" data-count="0">
    <span id="a">0</span> liked this
</button>
function handleClick() {
  var $this = $(this);
  var count = $this.data('count');

  // update state
  $this.data('count', count + 1);
  // update view
  $this.find('#a').text(count + 1);
}

Yes, that's also true that you don't have to use inline handlers.

Igor Bykov
  • 2,532
  • 3
  • 11
  • 19
  • I am quite new to jQuery, sorry for my ignorance, but what do you mean by 'storing state in a text node'? Thank you. – koder613 Sep 17 '20 at 16:54
  • @koder613 Hey! I referred to this **0** inside `0`. Storing values this way makes it slightly harder to read & modify them. Normally it's suggested to maintain this _state_ inside your JS code. – Igor Bykov Sep 17 '20 at 17:02
  • Thank you for for explaining. Also in your code, what is the purpose of the line `$this = $(this)`. Is it just to make referencing to $(this) two characters shorter? – koder613 Sep 17 '20 at 17:29
  • @koder613 exactly :) Feel free to drop it if you prefer `$(this)`. I just got used to storing references to everything in the begging of a function. – Igor Bykov Sep 17 '20 at 17:33
2

Because you have only one element inside button (i.e.: span) I would suggest a different approach without using jQuery. Disavantages:

  • inline event handler
  • i assume there is only one child

function foo(ele){
    ele.children[0].textContent = parseInt(ele.textContent) + 1;
}
<button onclick="foo(this)">
    <span id="a">0</span> liked this
</button>

As per your comment the code is:

document.querySelector('button').addEventListener('click', function(e) {
  this.children[0].textContent = parseInt(this.textContent) + 1;
});
<button id='b'>
    <span id="a">0</span> liked this
</button>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61