1

I have some livequery handlers which update the page content. I'd like to display the content only after they have fired (to prevent users seeing for a while the unchanged version). The content is loaded using normal AJAX.

So far I tried the following:

  1. get the ajax via html
  2. make it invisible (visibility: hidden)
  3. window.setTimeout(showContent, 100) - sets visibility to visible

I supposed this would work as there's a single JS thread for a single tab - so the timer should fire after all other operations finished. And it works in FF & IE. However in Chrome, sometimes I'm still seeing the unchanged content for a while - as if JS was threaded or interrupted by the timeout?

Or maybe there's a better way to achieve what I'm trying to do? (Without the timeout).

adamw
  • 8,038
  • 4
  • 28
  • 32
  • Why would you update the first request? Isn't better to call all the right data from the request itself? – yoda Feb 07 '11 at 09:33
  • Sure it would be better to generate the right thing in the first place, but some of the updates are layout-dependent, for example taking into account the actual width of the text (ellipsis). – adamw Feb 07 '11 at 09:40

2 Answers2

1
  • you can use the success callback
  • or you can return the javascript itself back and add it to the dom. (in which you'll specify the display mechanisms :) )
Shrinath
  • 7,888
  • 13
  • 48
  • 85
  • But I'm receiving the new content and updating the DOM in the success callback, so all the livequery/jquery events fire only after the call finishes. – adamw Feb 07 '11 at 09:59
  • then instead of setTimeout, you could fire your .show() call at the end of your call chain, no ? Anyway js is going to be single threaded... that means flow will go like this -> you call ajax -> success calls hide() -> hide()'s callback calls one of your update functions -> your update function calls .show().. isn't that working out ? – Shrinath Feb 07 '11 at 10:08
  • Unfortunately not, the livequery events are fired only after my method finishes. I was also thinking that the flow would go like this, but for some reason sometimes (in FF, Chrome, never in IE) the timeout is called before the livequery events. – adamw Feb 07 '11 at 11:11
  • make your display/show function to check a global variable before executing, if the variable is false, don't execute, just return false. you could set the variable at the end of your function chain ? – Shrinath Feb 07 '11 at 11:34
  • I ended up using the global $.livequery.queue.length, and in fact your answers led me to this solution, so thanks a lot! :) – adamw Feb 07 '11 at 12:33
  • @adamw : glad you arrived at a solution :) – Shrinath Feb 07 '11 at 12:36
0

It turns out that livequery uses a timeout internally do run the live queries, so it was a matter of timeout method ordering.

So I solved this waiting until the livequery queue clears (with some boundaries, if the user is crazy with his mouse and constantly produces events):

function run_after_livequery(method) {
    var tries = 0;
    function run_if_livequery_done() {
        if (!$.livequery.queue.length || tries >= 20) {
            method();
        } else {
            window.setTimeout(run_if_livequery_done, 50);
            tries++;
        }
    }

    window.setTimeout(run_if_livequery_done, 50);
}
adamw
  • 8,038
  • 4
  • 28
  • 32