Reputation: 4987
I am working on refactoring a JavaScript namespace for a site. The namespace leverages jQuery for selectors and events. Here is an example.
MyNamespace = {
eventElements : {
headerSectionA : $("h1.section-a");
headerSectionB : $("h1.section-b");
}
sectionA : function() {
// do stuff for section A here, such as
MyNamespace.eventElements.headerSectionA.click(function(){
// behavior A
});
}
sectionB : function() {
// do stuff for section B here, such as
MyNamespace.eventElements.headerSectionB.click(function(){
// behavior B
});
}
}
This is a distilled code sample. Imagine many eventElements, and many site sections that make use of subsets of those eventElements.
My question is whether jQuery traverses the DOM for all eventElements every time this script loads, or only when a function is called that uses that eventElement.
I want to avoid performance loss, but I am not sure if jQuery traverses the DOM when an eventElement property is declared, or only when an event is attached to the eventElement.
If there is a performance loss using the approach above, then I will branch within the namespace to only declare eventElements within the context of the section that makes use of those eventElements.
Upvotes: 0
Views: 214
Reputation: 24105
JavaScript is executed as expressions are encountered. So yes, if this is in your script file:
MyNamespace = {
eventElements : {
headerSectionA : $("h1.section-a"),
headerSectionB : $("h1.section-b")
}
// ...
}
Then $
is called and the DOM is traversed at the time the script is executed. This is bad on a couple levels:
$(document).ready
exists is to get around this problem)I'd adjust it to only do as much work as needed:
MyNamespace = {
eventElements : {
headerSectionA : "h1.section-a", // THESE BECOME STRINGS
headerSectionB : "h1.section-b"
}
,// ...
sectionA : function() {
// Call $ as late as possible
$(MyNamespace.eventElements.headerSectionA).click(function(){
// ...
});
}
}
Now if for whatever reason MyNamespace.eventElements.headerSectionA
must be a jQuery object before sectionA
is called, then you should at least wait to initialize them until the DOM is ready, in order to reduce the brittleness of the script itself:
// namespace defined as before
// wait until DOM is ready
$(document).ready(function() {
for(var selector in MyNamespace.eventElements) {
MyNamespace.eventElements[selector] = $(MyNamespace.eventElements[selector])
}
})
Upvotes: 3