This is neater than using a variable defined outside of the closure, but I was under the impression that attaching arbitrary data to DOM nodes was bad form.
Thoughts?
This is neater than using a variable defined outside of the closure, but I was under the impression that attaching arbitrary data to DOM nodes was bad form.
Thoughts?
The typical situation is creating a variable to a dom node, and then attaching an event handler to that dom node. The event handler has a reference to the dom node through its closure object, and the dom node has the reference to the event handler creating the circular reference. You must be careful to null out the event handler when you are done with it.
For arbitrary data, jquery provides a data() function that does the cleanup stuff for you. for event handlers, well, jquery's bind() (now renamed to on() ) is one of the first things you learn in jquery, and it (i assume) also deals with the IE bug.
I'm mainly curious about this in terms of programming style/best practices. Beside implications to the namespace of that node (which could be avoided with data()), it seems to me that it would be best to separate the setTimeout ID to a variable defined outside of that closure simply to make the code maintainable, for if there ever was another reason to interrupt the setTimeout.
However, due to the mention of closure at all by the interviewer, it seems that he felt that attaching it to the DOM node was the "best solution". Would you agree?
$(document).ready((function() {
$('input').keypress((function() {
var timeoutId = null;
return function() {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(function() {
$.ajax({ /* ... * /});
}, 200);
};
})());
});
// NB: this solution only works if there is one input.
// If there are more than one, you need to create a new closure for each one.On a broader level, an interesting question is: when is it good practice to attach a variable to a DOM node? I would say very rarely except perhaps in the case where what you are doing is assembling some kind of interface widget out of HTML elements. Then storing information about the widget's state with the dom node is what makes the most sense.
Since in the question, the task at hand is constructing an autocomplete widget, apparently from scratch without recourse to the many easily available robust and tested existing libraries, it does indeed make some sense to store the timeout state with the DOM node. If your goal is a robust reusable component, you want something that can cope with having many instances on a page. to do that and maintain the behavior of one on its own, you can either attach the state with the dom node, or create a framework that simulates doing that, but implements it in some other overly clever way.
Unfortunately, this is really easy to do with closures. For instance, patterns like this are pretty common:
var domElement = $("#someId");
domElement.click(function () {
domElement.style.color = "red";
});