views:

93

answers:

2

I'm trying to replace a bunch of innerHTML references in code with DOM-compliant node stuff.

<html>
    <body>hehe</body>
    <script type="text/javascript">
        var myDiv = document.createElement('div');
        myDiv.setAttribute('id', 'myDivID');
        document.getElementsByTagName('body')[0].appendChild(myDiv);
        var textNode = '<p>This will be dynamically generated.</p>';
        myDiv.appendChild(textNode);
    </script>
</html>

Sure, the script isn't supposed to be below the body, but if I place it above, the javascript returns the error:

document.getElementsByTagName("body")[0] is undefined

since the body doesn't exist yet.

But as it is now, the javascript returns the even more esoteric error on the "appendChild" step:

uncaught exception:
[Exception... "Could not convert JavaScript argument arg 0 [nsIDOMHTMLDivElement.appendChild]"
nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)"
location: "JS frame :: .....TestStuff/wut.jsp :: <TOP_LEVEL> :: line 8"
data: no]

So what's the deal, here? You can repalce the myDiv.setAttribute and myDiv.appendChild lines with getElementById references and the result is the same.

Edit: sorry, the above errors are firefox ones, not chrome ones. The chrome error is: Uncaught Error: NOT_FOUND_ERR: DOM Exception 8 on the myDiv.appendChild line. I don't get why myDiv wouldn't be on the DOM at this point, but chrome doesn't seem to think it is.

Edit 2: So, this line:

var textNode = '<p>This will be dynamically generated.</p>';

if made into

var textNode = document.createTextNode('< p>This will be dynamically generated.< /p>');

Will output text correctly. However, I want to know how to generate and append a chunk of html that will output as actual markup rather than pure text--something that can emulate innerHTML, essentially.

+2  A: 
var textNode = '<p>This will be dynamically generated.</p>';
myDiv.appendChild(textNode);

You need to create the <p> element and the text inside of it as distinct nodes. This should be:

var paragraph = document.createElement('p');
var textNode  = document.createTextNode('This will be dynamically generated.');

paragraph.appendChild(textNode);
myDiv    .appendChild(paragraph);

That's assuming that you really want the <p>...</p> element. If you can do without it then simply create the text node and append that to myDiv.

John Kugelman
Well, that's the issue... we need to be able to make a text node out of a long string of elements that would be infeasible to turn into nodes. This is what I dislike about XHTML-compliance.
Rujiel
+1  A: 

Is there a reason you don't just put your code into an onload handler? It sounds as if it would solve most of your problems, if not all.

Right now, you're trying to modify the DOM tree before the browser has finished parsing the XHTML.

Dori
This software needs to be able to write out page elements from a third party includes (< script type="text/javascript" src="http://mysite.com/something.jsp>), so no page elements could be assumed on my part to anchor an onload to.
Rujiel
Do you have any control over the external script? If you do, put it inside a function. If not, maybe that code is already inside a function? In either case, have a local `onload` handler call the external function. Otherwise, you're stuck—if you have no control over the external JavaScript, and it runs automatically before the DOM tree is fully created, and it tries to modify the DOM, it will occasionally fail. You can't modify something that doesn't exist.
Dori