PDA

View Full Version : Possible to dynamically insert a page and run javascript contained on that page?



snapple_pitchcock
01-18-2009, 03:56 AM
1) Script Title:

Dynamic Ajax Content


2) Script URL (on DD):

http://www.dynamicdrive.com/dynamicindex17/ajaxcontent.htm


3) Describe problem:

Is it possible to insert a page and execute javascript contained on that page? For example, is it possible to dynamically insert a page that contains the code:



<script type="text/javascript">
documment.write('hello world');
</script>


and then write "hello world" to the page that's been inserted? I have not had success doing this.

(My actual example is more complicated but this example contains the essence of my problem.)

jscheuer1
01-18-2009, 05:01 AM
No. If you do document.write() after the main or top page is loaded, it will overwrite the entire page. This is separate from the fact that different browsers may or may not run the script on import anyway.

snapple_pitchcock
01-18-2009, 05:09 AM
Thanks, John.

So if you were to try something less harmless than document.write, such as:


alert('Hello world');

it generally would not work when the page is dynamically inserted?

If so, this corroborates my experience: I tried to insert a javascript alert using Firefox and it didn't work.

jscheuer1
01-18-2009, 05:41 AM
Yes, it's a crap shoot if you know what I mean. I think earlier versions of Firefox would execute something as simple as an alert. I really don't keep up on the behavior in any given browser with things like that because there is no cross browser method at that level.

However, there is a new paradigm emerging in javascript as it relates to imported AJAX content. First of all the script(s) you might want to run against imported content should be on the 'top' page. These scripts cannot initialize onload in the usual way that many scripts do though, because the imported content will not be there yet. Polling is one way to attempt to deal with this issue, but it is inefficient.

Here is a very simple example of a script that will run against imported content, as well as content already present on the page:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
document.onclick = function(e){
e = e || window.event;
var t = e.target || e.srcElement;
if (t.className == 'qualifies')
alert('AhHa!');
}
</script>
</head>
<body>
<span class="qualifies">Click Me</span><br>
<span>Click me, but no dice</span>
</body>
</html>

If you were to import content to that page that also had an element with the class 'qualifies', and you clicked on it, it would give the alert, just like the one that's hard coded on the page. This can work with very complex code, but if the element clicked is a child of a qualifying element, walking the DOM tree upward from it would be required - fairly simple actually, but not a part of this very basic demo.

This works because instead of initializing or coding to the imported content, the script in this case is listening to the document.

Now, you can also go to the other extreme and simply hard code events to imported elements, but in most cases for that to be effective, there would still need to be a script on the 'top' page to evaluate the events.

But a simple example can demonstrate this technique with no script on the 'top' page. On an external page you may have:


<a href="#" onclick="alert('Hello World');return false">Say Hi</a>

If that is imported, it will work when clicked.

snapple_pitchcock
01-18-2009, 06:54 AM
John, thanks for the detailed reply. I understand what you mean about inserting content and integrating it with the existing DOM. I can see how you could insert a javascript snippet that causes an alert onclick or a snippet that works with a more complex script on the "top" page.

In this case, I guess what I'm looking for is something similar to "onload": insert the page dynamically, then run the javascript on the page. You mentioned polling as a way to institute a "listener" for new content, and I agree that'd be inefficient....unless you could trigger a listener right before inserting the content dynamically. The "listener" would be triggered onclick right before the content is inserted. The "listener" could ping the page a few times asking if an elementId is available and if/when the elementID is there, then the script could run. That way the script could be activated without an "onclick" or "mouseover" event.

Maybe it would be more sensible to insert the page dynamically, and then, when the readyState == 4/status==200 you could initiate the script...I've used something like this in the past; though I'm not sure it's applicable in this particular case. (I'm trying to combine a DB look up, dynamic insert and a map generated by the Google Maps API.)

Thanks again for taking the time to read and compose such a thoughtful response. Much appreciated!

jscheuer1
01-18-2009, 07:26 AM
Polling, if done as you describe, could be effective in the case you mention as I understand it.

I also like the onreadystatechange idea (there are so many approaches with AJAX). If you want to go that route, I've found that this type of syntax is pretty effective (for the onreadystatechange function):


if (request.readyState == 4 && (request.status == 200 || !/^http/.test(window.location.href))){
load up the external content;
setTimeout(function(){test added content in some way, if passed do something;}, 0);
}

The 0 timeout generally supplies all the delay that's needed at that point to check for an element or an element with a specific attribute(s) that may or may not have just been added. Care usually must be exercised though to make sure that such an element and your method for testing for it is unique.

snapple_pitchcock
01-18-2009, 07:34 AM
Awesome stuff, John.

Thanks again!