Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript, jQuery and 'this' : what's going on here?

This is more a question about what's going on in my code. It works, but I need a little bit enlightenment...

I'm using jQuery to create an event listener on an text input element. The HTML would simply be as follows:

<input type="text" id="autocomplete" size="50" />

I need to receive events whenever someone types something into that field, and to avoid being flooded with events I've set the event listener up with a timer so that my event listener code only runs if the user has not type anything for 125 ms:

jQuery('#autocomplete').keyup(function(e) {
  e.preventDefault();
  clearTimeout(this.timer);
  this.timer = setTimeout(function() {
    jQuery.getJSON([URL goes here], function(data) {
      // processing of returned data goes here.
    }
  }, 125);

console.log(this);
});

This works, but I'm not quite sure if I understand everything going on here. As you see from the above piece of code, I need to keep track of the ID of the timer which was created on the last event. I do that by storing it in this.timer. However, the this keyword in this case refers to the input element. This is what console.log outputs:

<input type="text" id="autocomplete" size="50" />

Is it OK to store the timer ID on the input element? For all I know, I could be doing something stupid. Is this "best practice", or would that be something very different?

like image 338
sbrattla Avatar asked Nov 02 '22 23:11

sbrattla


1 Answers

In general I prefer not to place any further values directly into the DOM object. As the DOM matures, there is a slim chance the namespace you choose could be used by the DOM for other purposes. As well as this other scripts could cause namespace conflicts, certainly with a variable named timer. If you must do this then use an obscure namespace to mitigate this risk. Older versions of IE also have strange behaviour when it comes to serialising a DOM node, you could end up with an actual attribute in the node called timer with a very odd value. As well as this, console.log does not return a list of the DOM node properties making debugging more complex than it should be.

In general it is better practice to leave the DOM as it is and reference its properties as defined by the document object. In my opinion it would be better practice to place the timer into the equivalent of a public static variable within an anonymous function along with your handler, this avoids any scope problems where you may accidentally overwrite your timer and keeps your code modular.

(function($) {

    // Static variable for this function
    var keyupTimer;

    // Event handler for keyup
    $('#autocomplete').keyup(function(event) 
    {
        event.preventDefault();

        clearTimeout(keyupTimer);

        keyupTimer = setTimeout(function()
        {
            $.getJSON([URL goes here], function(data)
            {
                // processing of returned data goes here.
            }
        }, 125);
    });
})(jQuery);
like image 160
David Barker Avatar answered Nov 11 '22 04:11

David Barker