Page 1 of 1

Javascript timing, and launching in responseText

Posted: Thu Aug 05, 2010 9:00 pm
by avivm3
I have two JS questions (forgive me if you think I should have these on separate posts):

1) I want to trigger an event after the line before it FINISHES filling the innerHTML of an element. Right now, the display function is called on my element before all its content is populated, making for a sloppy entrance.

2) I have some PHP code that results in an HTML and JS output. When the code is there the first time the page loads, the JS executes (a simple alert box). If the code is on the page as a result of an AJAX call and BECOMES the innerHTML of the element, the JS never executes. How do I get JS to execute after it's loaded view responseText (i.e.-A form is loaded via AJAX. Once the form is loaded, I want to run some JS that will do certain things to the form)?

Thanks!

Re: Javascript timing, and launching in responseText

Posted: Fri Aug 06, 2010 3:19 pm
by PHPHorizons
Hello avivm3,

I'm not sure about #1. It's one of those things I'd have to play around with to figure it out. Maybe someone else knows better.

But on #2, the responseText is a string. To get that javascript code in that string to be executed, you first need to isolate that code. This is best done by encoding the output (JSON or XML normally), but since you are displaying the page both without ajax and with ajax, that might be difficult. In any event, you can fall back on some good old regex to find the script tags and extract that javascript. Then you can run it through eval().

A better way to go is to use a dispatcher. A dispatcher will bring in javascript asynchronously. You can find a dispatcher in a JavaScript Library. I'm a YUI guy, so I can point you to a YUI based solution: http://bubbling-library.com/eng/api/doc ... dispatcher
I'm sure jQuery and other libraries have similar modules.

Cheers

Re: Javascript timing, and launching in responseText

Posted: Sat Aug 07, 2010 12:52 am
by avivm3
Hmm. So if I understood you correctly, I could feed the responseText into [something] that will extract the JS and then run it. If that's correct, I might have some follow-up questions when I research those options you mentioned for parsing out the script.

But even if I'm able to extract the scripts and then execute them, I wouldn't want to until the innerHTML is finished loading...which brings me back to question number one.

I just tested out some script and it worked...almost. So after my AJAX script starts replacing the innerHTML of an element (and if there is a callback function), I start a finite loop (for now, limited to 5). Each time the loop iterates, it compares the innerHTML to the responseText. If they match (or if it maxes out the loop), it launches my callback function. I've got a 1-second delay on the iteration, so it doesn't loop through all of the iterations in what amounts to the same instant. Everything seems to be working. The loop is successful, the 1 second delay works, but it always maxes out and never finds a match between the responseText and the innerHTML. I have also tested this code by having an alert box display the innerHTML if they aren't the same, and the content displayed IS the HTML that I'm looking for. I tried adding the valueOf() method, and that had the same result.

Why would these two strings not be equal to each other?

Here is the code that executes after I get a valid responseText from my AJAX request:

document.getElementById(responseElement).innerHTML=xmlhttp.responseText;

if(callbackFunction)
//(note: the callback function is going to show the DIV that is currently hidden but now loaded with new innerHTML content.)
{
var r=0;

for(r=0;r<=5;r++)
{
pausecomp(1000);
if(document.getElementById(responseElement).innerHTML.valueOf()==xmlhttp.responseText.valueOf()){callbackFunction();}
}
alert("I gave up and moved on");
callbackFunction();
}

Re: Javascript timing, and launching in responseText

Posted: Sat Aug 07, 2010 10:20 am
by PHPHorizons
Hello avivm3,

I wish I could help more, but I'd be groping in the dark trying to figure out what is happening there without being able to see the actual page.

With that said, there is one thing in particular that strikes me as a bit odd. Any time I see a deal where innerHTML is being checked for equality with something else, I have to stand back and think why is this being done that way. innerHTML is for display. I.e., it'd be like asking if web page 1 == web page 2. A better way to do it is to put a class on that element who's innerHTML we're dealing with (or a custom attribute) and ask if that element has a class name == to such and such (or a custom element with a value == to such and such). If you must compare the contents of the innerHTML, then perhaps you should md5 the contents before inserting that content into the element and attaching a class name of that md5 string.

Cheers

Re: Javascript timing, and launching in responseText

Posted: Sat Aug 07, 2010 11:19 am
by avivm3
PHP Horizons, you are right. I mean, the reason for wanting to check on the innerHTML, like you said, is for display. I need to affect the display of my form, and I can't do it until it has populated. So my innerHTML comparison was just an attempt at creating some sort of check (which is silly, when I remember that I may be feeding the browser some HTML, but it may very well adjust it (like handling a typo in a tag) and throw the whole thing off. I had put a hidden field at the end of most of the DIVs I was dealing with, and was going to tie a function into that. Instead, like you suggested, I could just look for the element instead of all the HTML.

I will try that. Thanks!

Re: Javascript timing, and launching in responseText

Posted: Sat Aug 07, 2010 12:08 pm
by PHPHorizons
You're welcome. I'm glad that helped out at least a little bit.

As far as how setting innerHTML works, I do believe that JavaScript execution will not proceed until the innerHTML has been set. Perhaps there are images or some other external resource that needs to load, and that may well extend past the call to innerHTML. It is possible to put an onload event on any images that need to load so that you can be sure those will be finished. But as far as the parsing of the html, and the browser fixing or doing whatever it might do with malformed html, all that will be finished before JavaScript execution moves on.

Another idea you might be able to use here is that you can create an element and leave it unattached to the DOM. Since it's not attached, the amount of processing time for the innerHTML call is much smaller (i.e., no browser repainting, etc.) and you will still be able to query elements in that detached and newly created container element. Then you can make any changes you need to make. When that is all done, you could plug that element into the DOM. (naturally if you have images or other external resources like a flash object, and if you need those to have a size (instead of being 0 width/0 height), then this method isn't going to be too helpful)

Cheers ;)

Re: Javascript timing, and launching in responseText

Posted: Sat Aug 07, 2010 10:21 pm
by avivm3
I do believe that JavaScript execution will not proceed until the innerHTML has been set. Perhaps there are images or some other external resource that needs to load, and that may well extend past the call to innerHTML.
Yes, there are pictures. But after the first time I run the script, the pictures are loaded and shouldn't burden future renderings. And yet, the animation that reveals the DIV is still choppy, like it's still trying to render the HTML. Is there a way to wait until it's fully "rendered" before I reveal it? (Or is this like asking for something to be visible and not visible at the same time...)

On the other issue - getting JS to launch from with a responseText - I used your idea about the onload attribute for an img. I use my PHP AJAX Processor Page to accumulate a list of JS functions inside a string (as the page builds). The last element is an image that has an onload attr which I just fill with the PHP string, and it totally works! (I might use that same method to trigger my "reveal" function for the first issue, and see if that timing is any better...)

Thanks for helping me brainstorm this one out!

Re: Javascript timing, and launching in responseText

Posted: Sun Aug 08, 2010 7:31 am
by PHPHorizons
The last element is an image that has an onload attr which I just fill with the PHP string, and it totally works!
Sweet! That's what I'm talking about ;)
And yet, the animation that reveals the DIV is still choppy
Are you using a js library for the animation, or is this totally your own implementation?

Re: Javascript timing, and launching in responseText

Posted: Sun Aug 08, 2010 3:08 pm
by avivm3
jquery 1.4.2. And I'm using the slideUp and slideDown methods.

Re: Javascript timing, and launching in responseText

Posted: Sun Aug 08, 2010 4:28 pm
by PHPHorizons
Well, you are using a library, so that's not the issue. Do you have the page accessible online?

Re: Javascript timing, and launching in responseText

Posted: Wed Aug 11, 2010 6:33 pm
by avivm3
Nothing I can make public at the moment. For now, I've lessened the symptoms by clearing the innerHTML of the elements I am hiding. So, if they re-display too soon, at least they are empty.

But now I have a new problem...I'll have to make a new post once I've surrounded the issue :?