A H A H - 5 months ago 15
HTML Question

Adding a <script> node on top of <body> from javascript in <head>

I want to insert some javascript code,


  1. That should be run before other javascript codes in the
    <body>
    run.

  2. As they manipulate html in
    <body>
    , that are inside
    <body>
    .



Normally i would put this javascript in a
<script>
tag right after the opening
<body>
tag. But I am not writing the html directly. Its generated for me by a program. (react-storybook). Its API allows to inject html inside
<head>
but not
<body>
.

<head>
<script></script> <-- I can inject a script tag here
</head>
<body>
<script></script> <-- I can't directly add this script tag but I need one here

<script>other js</script>
</body>


I tried putting my js in a
document
load
event handler, but they run after body is completely loaded so other js has already run.

I tried putting my js directly in the head then my js can't use
appendChild
on body, because at that point
document.body
is null.

Is there a way to insert a script tag satisfying both above requirements with accessing only the
<head>
?

Answer

I don't see any way to do this without probably breaking the tool you're trying to work within and doing some fairly nasty things. I suspect there's a better way to solve your underlying problem.

I tried putting my js directly in the head then my js can't use appendChild on body, because at that point document.body is null...

It's nasty and probably a bad idea, but you could force the body to be started:

document.write("<body>");

At that point, the parser will create the body element. You can then use appendChild (or just continue using the evil document.write). When the body is started again later in the normal course fo things, that second opening tag will be ignored.

It's not a good idea. react-storybook is open source. If there isn't a way to achieve your actual goal with it already, I suggest modifying it so you can rather than doing something like the above.

Here's an example, tested and working in Chrome, Firefox, IE11, IE8, and iOS Safari.
(Live copy on JSBin):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
  <script>
    (function() {
      var d = document.createElement("div");
      d.innerHTML =
        "This is the element appended to the body element " +
        "that we forced to be created using the evil " +
        "<code>document.write</code>";
      document.write("<body>");
      document.body.appendChild(d);
    })();
  </script>
</head>
<body>
<div>
This is the first element inside the body element in the markup.
</div>
</body>
</html>
Comments