0

So basically I have an external JS file that I need to host on someone else's page. This JS file uses document.write to write HTML on the page.

Right now it embeds the HTML where the JS file was included, but I want the HTML to be written to the top of the page, right after <body>.

Is there anyway to do this? Consider that the person embedding the JS file will not be able to simply place it right after the body tag.

kevinkt
  • 675
  • 10
  • 20
  • Untested theory but what if you redeclare document.write to create a container element, insert it where you need it and write the argument string inside it using innerHTML? Or try to convince the third party to not use blocking inflexible insertion methods ;) – jedifans Aug 14 '16 at 23:35
  • 1
    Do not use `document.write`. – Oriol Aug 14 '16 at 23:39
  • 1
    Because you can't do what you want with `document.write`. Because `document.write` is completely broken and dangerous and not allowed in XHTML. Because even the specification strongly discourages using it. – Oriol Aug 14 '16 at 23:43
  • Read more here: [Why is document.write considered a "bad practice"?](http://stackoverflow.com/questions/802854/why-is-document-write-considered-a-bad-practice) – blex Aug 14 '16 at 23:44
  • @Oriol Thanks man. What's the recommended alternative if I need to use a JS file to include CSS & HTML code? – kevinkt Aug 14 '16 at 23:44

4 Answers4

2

If you can, avoid using document.write. Here is a common way to insert a script, so that it gets executed:

document.addEventListener('DOMContentLoaded', function(){
    var s = document.createElement('script');
    s.src = "my_script.js";
    document.body.appendChild(s);
}, false);

If you have any other HTML you'd like to add, you could use innerHTML, but it's sometimes better to avoid using it, since it will replace all the elements (and maybe break some event listeners that were set before). Instead, you can use insertAdjacentHTML. Note that if a script is added via this method, it will not be executed:

document.addEventListener('DOMContentLoaded', function(){
    var code = '<style>.class{color:red}</style><div class="class">Hello</div>';
    document.body.insertAdjacentHTML('afterbegin', code);
}, false);

You can choose where the code gets appended by using these options: beforebegin, afterbegin, beforeend or afterend.

Community
  • 1
  • 1
blex
  • 22,377
  • 5
  • 35
  • 65
  • Thanks. My script also uses document.write to add divs, css, etc. Would createElement be the best choice for adding these as well? – kevinkt Aug 14 '16 at 23:53
  • @kevinkt It will work, but it will be a nightmare if you have lots of elements to insert. The example I provided is meant for just a script. Please see the changes to my answer. – blex Aug 15 '16 at 00:04
  • Awesome. This looks like what I need. Would this work even if my code section is massive (code as in the section with var code = "")? I have like 300 lines of code I need to inject there. – kevinkt Aug 15 '16 at 00:07
  • It will, but make sure there are no scripts in there for the second method, or they won't be executed. For scripts, you should use the first method. – blex Aug 15 '16 at 00:09
  • How do you use your first code snippet, but place the js file at the end of your body tag? Right before the closing body. – kevinkt Aug 15 '16 at 02:48
1

No, document.write writes the HTML in-line after the <script>. but you could modify innerHtml of the body element (or a <div> placed at the top etc.), but you might have to wait for the HTML to load first.

Seeing as you can't edit the script. what you need to do is place the script call in a <div> and use CSS to position the <div> at the top. (or use inline javascript to reorder the html elements on the page) so that the <div> is moved up to where you want it.

Jasen
  • 10,276
  • 2
  • 23
  • 40
1

Do not use document.write nor reparse the entire body with innerHTML.

You can use insertAdjacentHTML to insert an HTML string:

document.body.insertAdjacentHTML('afterbegin', htmlStr);

Or you can prepend some element:

var el = document.createElement('div');
// ... insert your data to `el`
document.body.insertBefore(el, document.body.firstChild);
Oriol
  • 225,583
  • 46
  • 371
  • 457
0

W3Scools says:

Definition and Usage The write() method writes HTML expressions or JavaScript code to a document.

The write() method is mostly used for testing: If it is used after an HTML document is fully loaded, it will delete all existing HTML.

Note: When this method is not used for testing, it is often used to write some text to an output stream opened by the document.open() method. See "More Examples" below.

Simon Müller
  • 444
  • 1
  • 3
  • 17