...

View Full Version : The DOM and IE's "document.body": What if there is no "<BODY>"?



tarh331_hax0r
03-06-2005, 08:07 PM
This is a question about the Document Object Model [the DOM] and Internet Explorer's "document" object.

According to this page at MSDN, a "document" object always has a member object named "body":

http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_document.asp

Now if I declare "<BODY>" explicitly, then the following code works just fine, and Internet Explorer reports that the document does indeed have a non-null body:


<body>
</body>

<script language="javascript">

if(document.body == null)
{
window.alert("\"document.body\" is null.");
}
else
{
window.alert("\"document.body\" is NOT null.");
}

</script>
However, if I do NOT declare "<BODY>" explicitly, then Internet Explorer reports that the document has a null body:


<script language="javascript">

if(document.body == null)
{
window.alert("\"document.body\" is null.");
}
else
{
window.alert("\"document.body\" is NOT null.");
}

</script>
MY QUESTION: If you do not declare "<BODY>" explicitly, is there some way to get the null pointer that lives at "document.body" to point to something that isn't null? Or are you stuck with a null body for the lifetime of the document?

Note that while "document" does have a createElement method, there is almost nothing else to work with: No appendChild, no swapNode, no replaceNode, and no removeNode.

For instance, the following won't work, because "document" doesn't have an appendChild method:


<script language="javascript">

var theBody = document.createElement("BODY");
document.body = document.appendChild(theBody);

</script>
I tried about a gazillion other ways to do this, but nothing seemed to work.

On a related note, if "<BODY>" is not declared explicitly, note that Internet Explorer will instantiate a "<HEAD>" object and place the javascript code therein. This is particularly strange, because there is no "document.head" object in the DOM hierarchy. You also see this with "document.title": If you set "document.title" to be something non-null, then Internet Explorer places the "<TITLE>" code within the "<HEAD>" code, so that it seems like this really ought to be an object known as "document.head.title" rather than just "document.title" [but of course, there is no "document.head" to contain a member object named "title"].

Now if we ask a document with no "<BODY>" to return all of its "<HEAD>" objects and then walk the tree from there, we find that the parentNode is non-null and has innerHTML, that the "grandParentNode" is non-null but lacks innerHTML, and finally that the "greatGrandParentNode" is null. My naive guess would be that the parentNode is something like "window.document" and that the grandparent is something like just plain old "window", but "window.document" is not supposed to have an innerHTML attribute [at least not according to the documentation sited above]:


<script language="javascript">

var theAlertString = "";

var theHeaderList = document.getElementsByTagName("HEAD");

theAlertString = "BREAKPOINT 1: ";

if(theHeaderList.length == 0)
{
theAlertString += "The document has no <HEAD>.";
}
else
{
theAlertString += "The document has a <HEAD>, and theHeaderList[0].innerHTML is as follows.\n";
theAlertString += theHeaderList[0].innerHTML;
}

window.alert(theAlertString);

theAlertString = "BREAKPOINT 2: ";

if(theHeaderList[0].parentNode == null)
{
theAlertString += "theHeaderList[0].parentNode is null.";
}
else
{
theAlertString += "theHeaderList[0].parentNode is NOT null, and has the following innerHTML.\n";
theAlertString += "\n";
theAlertString += theHeaderList[0].parentNode.innerHTML;
}

window.alert(theAlertString);

theAlertString = "BREAKPOINT 3: ";

if(theHeaderList[0].parentNode.parentNode == null)
{
theAlertString += "theHeaderList[0].parentNode.parentNode is null.";
}
else
{
theAlertString += "theHeaderList[0].parentNode.parentNode is NOT null, and has the following innerHTML.\n";
theAlertString += "\n";
theAlertString += theHeaderList[0].parentNode.parentNode.innerHTML;
}

window.alert(theAlertString);

theAlertString = "BREAKPOINT 4: ";

if(theHeaderList[0].parentNode.parentNode.parentNode == null)
{
theAlertString += "theHeaderList[0].parentNode.parentNode.parentNode is null.";
}
else
{
theAlertString += "theHeaderList[0].parentNode.parentNode.parentNode is NOT null, and has the following innerHTML.\n";
theAlertString += "\n";
theAlertString += theHeaderList[0].parentNode.parentNode.parentNode.innerHTML;
}

window.alert(theAlertString);

</script>
Any help would be most appreciated! Thanks!

codegoboom
03-07-2005, 01:45 AM
However, if I do NOT declare "<BODY>" explicitly, then Internet Explorer reports that the document has a null body...

The body object is available after window.onload, in that case.

liorean
03-07-2005, 02:42 AM
All elements with optional opening tags are filled in by the parser automatically, it's just at load time that they are missing. You shouldn't be trying to use the DOM at load time anyway.

tarh331_hax0r
03-08-2005, 01:33 AM
You shouldn't be trying to use the DOM at load time anyway.

Huh? Says who?

Personally, I was attempting this as something of an intellectual exercise - I was trying to write 100% pure DOM code, with no "static" HTML whatsover [although the DOM is so powerful that I'm tempted to adopt it for all my code].

Unfortunately, I've just about come to the conclusion that 100% pure DOM code can't be achieved with Internet Explorer - with IE, I'm afraid I'll only be able to achieve about 99.999% DOM, owing to the static "<BODY></BODY>".

liorean
03-08-2005, 02:01 AM
Huh? Says who?Says the fact that you're not guaranteed the existence of any element in the DOM tree, short of the document, before parsing is finished. In other words, document.write and document.writeln are the features that you can rely on being functional at load time, but stop working as soon as loading is finished. All other DOM functionality can only be relied upon after load has finished. That doesn't mean that it doesn't work in some cases even during load. It just means that you have no guarantee for, and shouldn't actually expect, it to work at load.

If you want an explanation to why this is so: the document is parsed into infoset (the internal representation of the document structure, if you wish), script parsing is based on partially finished infoset, and DOM is an interface to access or manipulate the infoset. Scripting is only probable to take place at document parse time in HTML and then only by consensus, not by spec. Infoset manipulation is not guaranteed to work until there is a finished infoset to manipulate, since it might be built in one piece. document.write and document.writeln affect document parsing, the rest of DOM affects infoset.
Personally, I was attempting this as something of an intellectual exercise - I was trying to write 100% pure DOM code, with no "static" HTML whatsover [although the DOM is so powerful that I'm tempted to adopt it for all my code].
Now, to finish that discussion, the answer is that you should use the onload event to trigger all DOM code, because that event is triggered by finishing loading.

Unfortunately, I've just about come to the conclusion that 100% pure DOM code can't be achieved with Internet Explorer - with IE, I'm afraid I'll only be able to achieve about 99.999% DOM, owing to the static "<BODY></BODY>".Ie works good enough in most cases, as long as you keep to doing things at times where the correct behavior is well defined.

glenngv
03-08-2005, 05:02 AM
Huh? Says who?

You should have known liorean. :D



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum