views:

46

answers:

2

I have the following loop:

for(var myScreen in wizardScreens){
    if(step==index)$(myScreen).show();
    else $(myScreen).hide();
    index++;
}

wizardScreens is defined as $(".wizardScreen", wizard);, where wizard is a DOM element. Within the loop, myScreen is set to a string, instead of being a DOM element. Can anyone explain why that is happening?

+2  A: 

jQuery collections already have a built-in iteration function:

wizardscreens.each(function (index, screen) {
  if (index == step)
    $(screen).show();
  else
    $(screen).hide();
}

Or perhaps even better for your use:

var activescreen = wizardscreens.eq(step);
activescreen.show();
wizardscreens.not( activescreen[0] ).hide();

Which avoids explicit iteration altogether.

hobbs
+1  A: 

In general, the answer is .each, but that calls a function for every DOM element, which is slower than using jQuery functions which manipulate all nodes in a jQuery object at once, so it's best to avoid it whenever possible. In this case it is definitely possible:

wizardScreens.hide().eq(step).show();
Tgr
Thanks (I wasn't aware of the `eq` function). I didn't use `hide` on all the objects as I wanted to be 100% sure that the object wouldn't flash by being hidden then reappearing
Casebash
DOM changes will only take effect after the script (actually, all scripts scheduled for the same time, so for example all event handlers that have fired for the action and all `setTimeout(foo,0)` calls) has fully run, so there would be no flash.
Tgr
@Tgr: Is this behavior documented?
Casebash
Not as far as I know (I'm not even sure where it could be - neither the ECMAScript nor the DOM specifications seem to be the right place) but that is how all major browsers work. See [this presentation](http://www.slideshare.net/nzakas/responsive-interfaces) for example.
Tgr