I am currently loading a lightbox style popup that loads it's HTML from an XHR call. This content is then displayed in a 'modal' popup using element.innerHTML = content
This works like a charm.
In another section of this website I use a Flickr 'badge' (http://www.elliotswan.com/2006/08/06/custom-flickr-badge-api-documentation/) to load flickr images dynamically. This is done including a script tag that loads a flickr javascript, which in turn does some document.write
statments.
Both of them work perfectly when included in the HTML. Only when loading the flickr badge code inside the lightbox, no content is rendered at all. It seems that using innerHTML
to write document.write
statements is taking it a step too far, but I cannot find any clue in the javascript implementations (FF2&3, IE6&7) of this behavior.
Can anyone clarify if this should or shouldn't work? Thanks.
In general, script tags aren't executed when using innerHTML. In your case, this is good, because the document.write
call would wipe out everything that's already in the page. However, that leaves you without whatever HTML document.write was supposed to add.
jQuery's HTML manipulation methods will execute scripts in HTML for you, the trick is then capturing the calls to document.write
and getting the HTML in the proper place. If it's simple enough, then something like this will do:
var content = '';
document.write = function(s) {
content += s;
};
// execute the script
$('#foo').html(markupWithScriptInIt);
$('#foo .whereverTheDocumentWriteContentGoes').html(content);
It gets complicated though. If the script is on another domain, it will be loaded asynchronously, so you'll have to wait until it's done to get the content. Also, what if it just writes the HTML into the middle of the fragment without a wrapper element that you can easily select? writeCapture.js (full disclosure: I wrote it) handles all of these problems. I'd recommend just using it, but at the very least you can look at the code to see how it handles everything.
EDIT: Here is a page demonstrating what sounds like the effect you want.
I created a simple test page that illustrates the problem:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Document Write Testcase</title>
</head>
<body>
<div id="container">
</div>
<div id="container2">
</div>
<script>
// This doesn't work!
var container = document.getElementById('container');
container.innerHTML = "<script type='text/javascript'>alert('foo');document.write('bar');<\/script>";
// This does!
var container2 = document.getElementById('container2');
var script = document.createElement("script");
script.type = 'text/javascript';
script.innerHTML = "alert('bar');document.write('foo');";
container.appendChild(script);
</script>
</body>
</html>
This page alerts 'bar' and prints 'foo', while I expected it to also alert 'foo' and print 'bar'. But, unfortunately, since the script
tag is part of a larger HTML page, I cannot single out that tag and append it like the example above. Well, I can, but that would require scanning innerHTML
content for script
tags, and replacing them in the string by placeholders, and then inserting them using the DOM. Sounds not that trivial.
Use document.writeln(content);
instead of document.write(content)
.
However, the better method is using the concatenation of innerHTML
, like this:
element.innerHTML += content;
The element.innerHTML = content;
method will replace the old content with the new one, which will overwrite your element's innerHTML!
Whereas using the the +=
operator in element.innerHTML += content
will append your text after the old content. (similar to what document.write
does.)
document.write
is about as deprecated as they come. Thanks to the wonders of JavaScript, though, you can just assign your own function to the write
method of the document
object which uses innerHTML
on an element of your choosing to append the supplied content.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With