CodingBison

The document object also comes with a method that allows us to write to an HTML page: write() method. A very popular method in the recent past, the use of document.write() is now generally discouraged. Let us understand the motivation behind this advice.

The method document.write() has a handful of drawbacks. First, when executed after the page has loaded, it can potentially erase all of the existing content. Second, if a part of the HTML page uses document.write() during loading, then the page loading would be blocked until document.write() returns. Third, document.write() does not provide us the precision to insert text at a desired location. Lastly, document.write() does not work with XML.

However, having said that, for simpler light-weight documents, we can use document.write() if we do not have to call it after the page has loaded. can use it. However, it is quite likely that a page that starts as a light-weight page can grow over time when new developers take an existing page and extend its functionality. Another use-case is when you intentionally want to overwrite the content in an embedded frame/iframe, then document.write() would be a quick way to handle that. Still, it should be used with caution!

As we have seen in the earlier examples, one good alternative to document.write() is to use innerHTML property of an HTML element. We can use a "div" element, since <div> elements come with innerHTML property; several, but not all, HTML elements have innerHTML property. It is a good idea to create a div element using DOM's createElement() method and then add it to the body of the page using appendChild() method. With this method, when we write to the innerHTML of the div element, it is only the div element that gets modified and the rest of the page remains as-it-is.

Even though innerHTML is a proprietary property from Internet Explorer, it is well-supported by all browsers.

Let us use a simple example to demonstrate that document.write() can erase content from an existing HTML page. In this example (provided below), we embed JavaScript code that writes on the page asynchronously. Once the HTML page has loaded, this code uses setTimeout() method to wake up after 1000 mill-seconds. After waking up, it calls wakeUpAndWriteSomething() function that uses document.write() to add text on the page. We deliberately put a timer (using setTimeout) because that allows us to see the initial HTML content and then after 1 second, we see that document.write() erases it. If we were to use "window.onload = wakeUpAndWriteSomething;", then the initial HTML content would be erased as soon as the page would load.

 <!doctype html>
 <html>
 <body>

 <img src="./gandalfLOTR.png" id="idImage"></img>

 <p> A wizard's To-Do list: </p>

 <ol>
 <li>Practice Spells</li>
 <li>Visit Bilbo Baggins</li>
 <li>Repair broken staff</li>
 </ol>

 <script type="text/javascript">

 function wakeUpAndWriteSomething() {
     document.write("Using document.write() is not a good practice!");
 }

 //Wake up after 1000 milli-seconds.
 setTimeout(wakeUpAndWriteSomething, 1000);
 </script>

 <body> t
 </html>

When we load the above page, we would see that when document.write() writes the provided text on the page, it completely erases the earlier content. Thus, for cases, where the page needs to interact and write something after the initial loading of page is complete, using document.write() may lead to surprising behavior.

For the sake of completeness, we provide the version of the earlier page using the innerHTML property. With this change, we find that innerHTML does not erase existing content of the page.

 <!doctype html>
 <html>
 <body>

 <img src="./gandalfLOTR.png" id="idImage"></img>

 <p> A wizard's To-Do list: </p>

 <ol>
 <li>Practice Spells</li>
 <li>Visit Bilbo Baggins</li>
 <li>Repair broken staff</li>
 </ol>

 <script type="text/javascript">
 var elem = document.createElement("div");
 var bodyElem = document.getElementsByTagName("body")[0]; 
 bodyElem.appendChild(elem);

 function wakeUpAndWriteSomething() {
     elem.innerHTML = "Using document.write() is not a good practice!";
 }

 //Wake up after 1000 milli-seconds.
 setTimeout(wakeUpAndWriteSomething, 1000);
 </script>

 <body>
 </html>

As a last note, we would like to mention that for cases, where we have to add a large number of small chunks (streams) of information to innerHTML, then we should avoid appending innerHTML with every update. Instead, we should resort to batching, where we collect enough of the small chunks into a local string variable and then append that to the innerHTML property. This way, we would avoid overwhelming the rendering of the page!





comments powered by Disqus