views:

454

answers:

1

Hi,

I have a page that on a certain action makes an iframe visible and fills the iframe with some HTML (say for example a multi-select box and an ok button).

The OK button on the iframe has the onClick method defined kinda like this:

onClick="parent.hideIFrame();parent.processMultiSelectBox();"

When User clicks OK on the iframe (presumably after playing with the multi-select box), I'd like the iFrame to disappear immediately and then the selected values in the multi-select box can be processed. But this is not what's happening. The iFrame remains visible during the time the other function runs and disappears only after the second function finishes.

The hideIFrame function is pretty straightforward:

function hideIFrame() {
  frmObj = document.all.iFrameID;
  if(frmObj) {
    frmObj.style.visibility = "hidden";
  }
}

I've paraphrased the above function for clarity (removed some indicator variable assignments etc.)

The second function actually loops on all the options in the multi-select object and does stuff with it. This takes about a half a second and only after that is done, does my iFrame disappear. It is a little bothersome to see it linger for half a second when I click ok.

My question is whether there is some way I can make the darn thing disappear faster. Speaking in "classical C" lingo, is there a "flush" for the change in visibility to happen immediately?

I did notice that if I put an "alert" as the first line in my second function, the iframe disappears immediately but now it is the OK on the alert box that lingers for the time it takes the second function to finish.

Thanks.

EDIT: Based on DDaviesBrackett's answer, this is what I ended up doing:

The onclick in the iframe changed to:

onClick="parent.hideAndProcessMultiSelectBox(parm1, parm2);"

The hideAndProcessMultiSelectBox function was defined as:

function hideAndProcessMultiSelectBox( parm1, parm2 ) {
   hideIFrame();
   setTimeout( function() { processMultiSelectBox( parm1, parm2 ); }, 0 );
}

Voila.. no delay..

+3  A: 

You've gotten to the root of your problem already; document reflow doesn't happen until the current JS thread is done (so as not to repaint lots of times during JS execution). You need to return control to the browser before doing your expensive processing.

The simplest way to achieve that, though it doesn't make for obvious code in the slightest, is to call processMultiSelectBox in a setTimeout with a delay of 0:

onClick="parent.hideIFrame();parent.setTimeout(parent.processMultiSelectBox,0);"

If you need to pass parameters to the thing you're setting a timeout on, you have two options: set a timeout on a string that evals to Javascript (bad, bad, very bad, horrible) or define an anonymous function that calls the one you're interested in:

onClick="parent.hideIFrame();parent.setTimeout(function(){parent.processMultiSelectBox(foo, bar, 'baz');},0);"

RSolberg's response may also help, though there's a difference between visibility:hidden and display:none.

DDaviesBrackett
You might be on to something here. I'm just wrestling with the parameters I need to pass to the "processMultiSelectBox". Once I can get them to go, I'll update.. Thanks.
Adnan
answer edited to provide a mechanism to pass parameters to the timeouted function.
DDaviesBrackett
Yes this did work. I'm still having problems passing parameters to the function, but I tested it with a dummy function which does a long nasty nested loop calculation.
Adnan
I don't see the edits to the answer
Adnan
should be there now. =)
DDaviesBrackett
See it now.. Thanks
Adnan
Works like a charm. Thanks so much!
Adnan
I edited the question with my final implementation if interested.
Adnan