From Here to There
This is <b>some bolded</b> text.
And to create that, we'd have to use:
text1 = document.createTextNode("This is ");
bTag = document.createElement("b");
textB = document.createTextNode("some bolded");
text2 = document.createTextNode(" text.");
bTag.appendChild(textB);
document.body.appendChild(text1);
document.body.appendChild(bTag);
document.body.appendChild(text2);
Wow, that sure was a lot of work for such a simple thing, which we could have just done:
document.body.innerHTML="This is <b>some bolded</b> text.";
As you can see, creating each little element can be very can become tedious and time-consuming. This is one reason why ranges are needed. A range is an area (or range) of any HTML (or XML) content. It can span across multiple tags, in between text nodes, etc.... This is major enhancement in Level 2. You can again hear about this from the "horse's mouth" in somewhat technical discussions at Document Object Model Core and Document Object Model Range, and there's a good article on ranges by Jeffrey Yates, which I recommend you read. Although we won't discuss the details of ranges as that could be a long discussion (the article by Jeffrey Yates, link above, explains about ranges), we will use it to change a layer's content. Here's the proper means of changing a layer's content (works in NS 6 but not IE 5) by W3C DOM Standard using ranges. Consider this function:
function
writeLayerNSSix(node,txtHTML){
var newRange = document.createRange();
newRange.selectNodeContents(node);
newRange.deleteContents();
var newHTML = newRange.createContextualFragment(txtHTML);
node.appendChild(newHTML);
}
Let's apply it to replace the text in "span1":
<div id="div1">
<span id="span1">This
is the text of SPAN1</span>
This text is not
in a span tag.
</div>
<script>
writeLayerNSSix(document.getElementById("span1"),"Now,
this is the <b>NEW</b> text for <i>SPAN1</i><b>!</b>");
</script>
Our document now looks like:
<div id="div1">
<span id="span1">Now,
this is the <b>NEW</b> text for <i>SPAN1</i><b>!</b></span>
This text is not
in a span tag.
</div>
Recreate our generic writeLayer() function.
I should also note the function we created to change a layer's content (way
back when we used innerHTML) is not W3C compliant, even though
it does work in NS 6. To make it W3C compliant, our code is going to be a little
longer. However, before we begin, we must learn a way to distinguish between
browsers IE 5 and NS 6. We could use if(document.getElementById&&!document.all)
and that will work, but what about IE 6? IE 6 supports document.all,
and it will return false for that statement and keep on using the older "innerHTML
method," when it could use the W3C compatible way, like NS 6. So, since
IE 5 and IE 5.5 don't support getAttributeNode() (which we haven't
discussed in this article, but you can find more information about it from W3C)
for elements, we can use if(document.body.getAttributeNode), knowing
the NS 6 and IE 6 support that feature and will return true for that while IE
5 and other browsers will return false for that if() statement. In light of
this,
let's rewrite our function to change a layer's content:
function writeLayer(layerID,txt){
if(document.body.getAttributeNode){
node
= document.getElementById(layerID);
var
newRange = document.createRange();
newRange.selectNodeContents(node);
newRange.deleteContents();
var
newHTML = newRange.createContextualFragment(txtHTML);
node.appendChild(newHTML);
}else
if(document.getElementById){
document.getElementById(layerID).innerHTML=txt;
}else
if(document.all){
document.all[layerID].innerHTML=txt;
}else
if(document.layers){
with(document.layers[layerID].document){
open();
write(txt);
close();
}
}
}
Notice that we just pass the layerID, rather than the node. This is added for
compliance, and I also added this line which was not included in our writeLayerNSSix()
function to accomplish this:
node = document.getElementById(layerID);
