admin管理员组

文章数量:1134247

It seems that experienced web developers frown upon using document.write() in JavaScript when writing dynamic HTML.

Why is this? and what is the correct way?

It seems that experienced web developers frown upon using document.write() in JavaScript when writing dynamic HTML.

Why is this? and what is the correct way?

Share Improve this question edited Sep 4, 2020 at 18:18 Caitlin Webb 33 bronze badges asked Oct 7, 2009 at 19:09 Gary WilloughbyGary Willoughby 52.5k42 gold badges139 silver badges204 bronze badges 5
  • 6 JQuery. I didn't add this as an actual answer, but I came close. It handles dom manipulation properly, while letting you write something simple like this: $("<div><span>text</span><div>sub</div></div>").appendTo('body'); – John Fisher Commented Oct 7, 2009 at 19:38
  • 2 This is a case where the jQuery meme actually makes sense. "I see you're trying to write HTML using JavaScript. You should totally drop that and use jQuery!" – Adam Bellaire Commented Oct 7, 2009 at 19:50
  • 4 jQuery is by no means the "correct" way to create HTML in JavaScript. It is written in JavaScript and will use one or more of the methods in the answers below, with the disadvantage that as a general purpose library it will not be making the informed choices of strategy for each situation that you as a developer would have. – Tim Down Commented Oct 8, 2009 at 8:19
  • 1 @Tim: It is no more "correct" or "incorrect" than any of the methods given, but it is a perfectly valid approach. There is no one answer that is "correct" in all situations. Your given "disadvantage" is merely a characteristic: I may or may not to spend my time analyzing optimal strategies for HTML production when the potential benefits are marginal. Depending on your choice, transparently managing that complexity could be an advantage or a disadvantage. One may decide to use jQuery until and unless there is a need for a more optimal strategy. – Adam Bellaire Commented Oct 8, 2009 at 15:13
  • 1 @Adam - Well argued. "disadvantage" is still accurate in terms of writing the most efficient code but I take your point that the gain in efficiency will not always be important enough to outweigh the convenience of jQuery's method, if and only if jQuery is already being used for another non-trivial task on the page. It's certainly not a job worth using jQuery for on its own. – Tim Down Commented Oct 8, 2009 at 18:50
Add a comment  | 

13 Answers 13

Reset to default 64

document.write() will only work while the page is being originally parsed and the DOM is being created. Once the browser gets to the closing </body> tag and the DOM is ready, you can't use document.write() anymore.

I wouldn't say using document.write() is correct or incorrect, it just depends on your situation. In some cases you just need to have document.write() to accomplish the task. Look at how Google analytics gets injected into most websites.

After DOM ready, you have two ways to insert dynamic HTML (assuming we are going to insert new HTML into <div id="node-id"></div>):

  1. Using innerHTML on a node:

    var node = document.getElementById('node-id');
    node.innerHTML('<p>some dynamic html</p>');
    
  2. Using DOM methods:

    var node = document.getElementById('node-id');
    var newNode = document.createElement('p');
    newNode.appendChild(document.createTextNode('some dynamic html'));
    node.appendChild(newNode);
    

Using the DOM API methods might be the purist way to do stuff, but innerHTML has been proven to be much faster and is used under the hood in JavaScript libraries such as jQuery.

Note: The <script> will have to be inside your <body> tag for this to work.

document.write() doesn't work with XHTML. It's executed after the page has finished loading and does nothing more than write out a string of HTML.

Since the actual in-memory representation of HTML is the DOM, the best way to update a given page is to manipulate the DOM directly.

The way you'd go about doing this would be to programmatically create your nodes and then attach them to an existing place in the DOM. For [purposes of a contrived] example, assuming that I've got a div element maintaining an ID attribute of "header," then I could introduce some dynamic text by doing this:

// create my text
var sHeader = document.createTextNode('Hello world!');

// create an element for the text and append it
var spanHeader = document.createElement('span');
spanHeader.appendChild(sHeader);

// grab a reference to the div header
var divHeader = document.getElementById('header');

// append the new element to the header
divHeader.appendChild(spanHeader);
  1. DOM methods, as outlined by Tom.

  2. innerHTML, as mentioned by iHunger.

DOM methods are highly preferable to strings for setting attributes and content. If you ever find yourself writing innerHTML= '<a href="'+path+'">'+text+'</a>' you're actually creating new cross-site-scripting security holes on the client side, which is a bit sad if you've spent any time securing your server-side.

DOM methods are traditionally described as ‘slow’ compared to innerHTML. But this isn't really the whole story. What is slow is inserting a lot of child nodes:

 for (var i= 0; i<1000; i++)
     div.parentNode.insertBefore(document.createElement('div'), div);

This translates to a load of work for the DOM finding the right place in its nodelist to insert the element, moving the other child nodes up, inserting the new node, updating the pointers, and so on.

Setting an existing attribute's value, or a text node's data, on the other hand, is very fast; you just change a string pointer and that's it. This is going to be much faster than serialising the parent with innerHTML, changing it, and parsing it back in (and won't lose your unserialisable data like event handlers, JS references and form values).

There are techniques to do DOM manipulations without so much slow childNodes walking. In particular, be aware of the possibilities of cloneNode, and using DocumentFragment. But sometimes innerHTML really is quicker. You can still get the best of both worlds by using innerHTML to write your basic structure with placeholders for attribute values and text content, which you then fill in afterwards using DOM. This saves you having to write your own escapehtml() function to get around the escaping/security problems mentioned above.

Perhaps a good idea is to use jQuery in this case. It provides handy functionality and you can do things like this:

$('div').html('<b>Test</b>');

Take a look at http://docs.jquery.com/Attributes/html#val for more information.

You can change the innerHTML or outerHTML of an element on the page instead.

I'm not particularly great at JavaScript or its best practices, but document.write() along with innerHtml() basically allows you to write out strings that may or may not be valid HTML; it's just characters. By using the DOM, you ensure proper, standards-compliant HTML that will keep your page from breaking via plainly bad HTML.

And, as Tom mentioned, JavaScript is done after the page is loaded; it'd probably be a better practice to have the initial setup for your page to be done via standard HTML (via .html files or whatever your server does [i.e. php]).

element.InnerHtml= allmycontent: will re-write everything inside the element. You must use a variable let allmycontent="this is what I want to print inside this element"to store the whole content you want inside this element. If not each time you will call this function, the content of your element will be erased and replace with the last call you made of it.

document.write(): can be use several times, each time the content will be printed where the call is made on the page.

But be aware: document.write() method is only useful for inserting content at page creation . So use it for not repeating when having a lot of data to write like a catalogue of products or images.

Here a simple example: all your li for your aside menu are stored in an array "tab", you can create a js script with the script tag directly into the html page and then use the write method in an iterative function where you want to insert those li on the page.

<script type="text/javascript">
document.write("<ul>");
for (var i=0; i<=tab.length; i++){
    document.write(tab[i]);
    }document.write("</ul>");
</script>`

This works because Js is interpreted in a linear way during the loading. So make sure your script is at the right place in your html page.You can also use an external Js file, but then again you must declare it at the place where you want it to be interpreted.

For this reason, document.write cannot be called for writing something on your page as a result of a "user interaction" (like click or hover), because then the DOM has been created and write method will, like said above, write a new page (purge the actual execution stack and start a new stack and a new DOM tree). In this case use:

element.innerHTML=("Myfullcontent");

To learn more about document's methods: open your console: document; then open: __proto__: HTMLDocumentPrototype

You'll see the function property "write" in the document object. You can also use document.writeln which add a new line at each statement. To learn more about a function/method, just write its name into the console with no parenthesis: document.write; The console will return a description instead of calling it.

There are many ways to write html with JavaScript.

document.write is only useful when you want to write to page before it has actually loaded. If you use document.write() after the page has loaded (at onload event) it will create new page and overwrite the old content. Also it doesn't work with XML, that includes XHTML.

From other hand other methods can't be used before DOM has been created (page loaded), because they work directly with DOM.

These methods are:

  • node.innerHTML = "Whatever";
  • document.createElement('div'); and node.appendChild(), etc..

In most cases node.innerHTML is better since it's faster then DOM functions. Most of the time it also make code more readable and smaller.

Surely the best way is to avoid doing any heavy HTML creation in your JavaScript at all? The markup sent down from the server ought to contain the bulk of it, which you can then manipulate, using CSS rather than brute force removing/replacing elements, if at all possible.

This doesn't apply if you're doing something "clever" like emulating a widget system.

The document.write method is very limited. You can only use it before the page has finished loading. You can't use it to update the contents of a loaded page.

What you probably want is innerHTML.

I think you should use, instead of document.write, DOM JavaScript API like document.createElement, .createTextNode, .appendChild and similar. Safe and almost cross browser.

ihunger's outerHTML is not cross browser, it's IE only.

Use jquery, look how easy it is:

    var a = '<h1> this is some html </h1>';
    $("#results").html(a);

       //html
    <div id="results"> </div>

Nowadays you can use document.currentScript like so

<script>
    document.currentScript.outerHTML = "<p>Hello world!!</p>"
</script>

which will replace that <script> element in the DOM with the <p>Hello world!!</p>

So, technically you could then do something like this...

<html>
    <script>
        document.currentScript.outerHTML = `
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Hello</title>
                <link rel="stylesheet" href="/css/style.css">
            </head>
            <body>
                <h1>Hello world!</h1>
            </body>
        `
    </script>
</html>

If you really want to do it properly you should use a framework like React or a standalone html-in-javascript library like ht.js then you could use functions to replace html like so...

<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/html-in-javascript/htjs.min.js"></script>
        <script>
            const { fragment, meta, title, link } = htjs;

            document.currentScript.outerHTML = 
            fragment(
                meta({ charset: "UTF-8" }),
                meta({ name: "viewport", content: "width=device-width, initial-scale=1.0" }),
                title("Welcome!"),
                link({ rel: "stylesheet", href: "/css/style.css" })
            )
        </script>
    <body>
        <script>
            const { body, h1, p } = htjs;

            document.body.outerHTML = 
            body({ class: "home-page" }
                h1("Hello World!"),
                p("this is fun!!")
            )        
        </script>
    </body>
</html>

本文标签: What is the correct way to write HTML using JavascriptStack Overflow