Aleksander Ciecierski
Aleksander Ciecierski

Reputation: 23

Create a custom element in place where the code was initialized

I'm trying to create an element using JavaScript in place where the script was initialized.

I need to be able to just call a function for the element to appear just after the <script> tag in my HTML document.

I tried this code but I don't know how to actually create an element.

function createElement() {

  var container = document.createElement('div');
	container.setAttribute("class", 'someDiv');
	document.createElement(container);
  
}
.someDiv {
  height: 100px;
  width: 100px;
  background-color: gold;
}
<body>

<script>
  createElement("div", "someDiv");
</script>

</body>

Upvotes: 0

Views: 349

Answers (4)

mattsven
mattsven

Reputation: 23293

document.currentScript seems to have good browser support, and will give us the script element containing the code currently being executed.

If what you'd like to do is replace the current script with some other element, you use it like this:

<script>
  const replacementText = document.createTextNode("hi, I'm the replacement!");

  document.currentScript.parentNode.replaceChild(replacementText, document.currentScript);
</script>

If you simply want to insert an element after the current script, without replacing it:

<script>
  const newText = document.createTextNode("hi, I'm new text!");
  const currentScript = document.currentScript;

  currentScript.parentNode.insertBefore(newText, currentScript.nextSibling);
</script>

Here's a more complex example using prewritten HTML:

<script>
  const currentScript = document.currentScript;
  
  const templateFragment = (function(){
    const templateEl = document.createElement("template");
    templateEl.innerHTML = `
    <ul>
      <li>Hi!</li>
      <li>I am a list!</li>
    </ul>
    `;
    
    return templateEl.content;
  })();

  currentScript.parentNode.insertBefore(templateFragment, currentScript.nextSibling);
</script>

Upvotes: 1

Shidersz
Shidersz

Reputation: 17190

You can use .insertBefore() to add some element before the next sibling of your script. To reference your script, you could add an id attribute to it:

.someDiv {
  height: 100px;
  width: 100px;
  background-color: gold;
}
<body>
  <p>I'm inside the body, before the script TAG</p>
  <p>New element should appear just after this text...</p>
  
  <script id="myScript">
  
    function createElement()
    {
      var container = document.createElement('div');
      container.setAttribute("class", 'someDiv');
      var script = document.getElementById("myScript");
      script.parentNode.insertBefore(container, script.nextSibling);
    }

    createElement();

  </script>

  <p>I'm inside the body, but after the script TAG</p>

</body>

Upvotes: 0

Scott Marcus
Scott Marcus

Reputation: 65835

Using document.currentScript, we can get a reference to the script element where the code is running and then using .nextElementSibling, we can get the next sibling node that is an element. Finally, with .insertBefore and .appendChild(), we can insert the new element just before the element passed in as an argument (the sibling that was found earlier or body if none was found).

NOTE: Don't call your function createElement as it can cause a naming conflict with document.createElement().

This will insert an element just after the script element.

.someDiv {
  height: 100px;
  width: 100px;
  background-color: gold;
}
<head>
 <script>
   function create(type, style) {
     var container = document.createElement(type);
     container.classList.add(style);  // Best way to add a class
     container.textContent = "Hello!";

     let sibling = document.currentScript.nextElementSibling;
     if(sibling){
       // Insert the new element before the next sibling
       sibling.parentNode.insertBefore(sibling, container)
     } else {
       // Insert the new element at the end of the body
       document.body.appendChild(container);  
     }
   }
 </script>
</head>
<body>

  <p>The new element should be right below this.</p>
  <script>
    create("div", "someDiv");
  </script>
  <p>The new element should be right above this.</p>

</body>

Upvotes: 1

Carl Edwards
Carl Edwards

Reputation: 14454

You could use insertBefore and target insertion point as the script like so:

var script = document.querySelector('script:last-of-type');
var container = document.createElement('div');

document.body.insertBefore.insertBefore(script, container);

Upvotes: 1

Related Questions