I'm working on a jQuery plugin (a jQuery UI widget) called Smooth Div Scroll where I need to store references to intervals that are specific to each individual instance of the plugin on the page. If i just write something like this:
var myInterval = setInterval(function() { alert("Hi!"); }, 100);
...the variable myInterval will actually be window.myInterval and it will be shared by all instances of the plugin on the page. So when I try setting or clearing an interval for an instance, the interval for all instances will be set/cleared since they are all referencing the same window variable.
Looking through jQuery API I found the method .data which is used to store arbitrary data associated with the matched elements and since e开发者_如何学运维ach instance of the plugin has a corresponding DOM element. Perfect! Using this method I can store data that is specific to the matched element. So I have structured my code like this (where el is a reference to the matched element):
el.data("myInterval", setInterval(function() { alert("Hi!"); }, 100));
To some extent this works since the different instances of the plugin no longer reference the same variable (interval). But I have noticed that if I have a page with 2-3 instances of my plugin and I set an interval that is the same for each instance, only the first instance starts its interval. But if the timer of the interval is small, only some of the elements start their interval.
I haven't done any deep digging in the actual values but if I have three instances of the plugin on one page and the interval is set to 5, like this:
el.data("myInterval", setInterval(function() { alert("Hi!"); }, 5));
...only the first instance will start. If I increase it to 20-30, two of the instances will start and if I increase it further to, say, 50 all three instances start. This is so weird?!
My questions are these:
Is storing a reference to an interval (using .data) a good idea? If so, what could be the cause of the failed intervals?
Please help me out with this one - I'm stumped! If you want the actual source code, check out the plugin page (link at the top of this post).
/Thomas Kahn
The return value of setInterval and setTimeout are just integers used internally to reference the timeouts, so storing an integer with .data isn't a problem.
Having looked deeper into the code and probed it a bit, it seems like the problem is not related to the storage of the intervals in el.data. The intervals are stored just fine. I suspect the problem is related to routines that are executing in the wrong order in the code. The correct order should be:
- Load a chunk of HTML-content (images) using jQuery's load().
- Calculate the total width of all these elements.
- Start the interval that scrolls these imags.
The problem seems to be that the routine that calculates the total width of all the elements is triggered before/at the same time as the content is loaded through AJAX using jQuery load. The result is that the calculated total width of the the loaded elements is 0 (zero) and the scrolling routine grinds to a halt since there's no point in scrolling something that has a width of zero.
精彩评论