208

I am creating a light box in pure JavaScript. For that I am making an overlay. I want to add this overlay to body but I also want to keep the content on the page. My current code adds the overlay div but it also removes the current contents in body. How to add div element and keep contents on body?

var el = document.getElementById('element');
var body = document.getElementsByTagName('body');
el.innerHTML = '<p><a id="clickme" href="#">Click me</a></p>';
document.getElementById('clickme').onclick = function (e) {
    e.preventDefault();
    document.body.innerHTML = '<div style="position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>';
}
Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
Om3ga
  • 30,465
  • 43
  • 141
  • 221
  • 4
    have you try to append it like : document.body.innerHTML = '
    '+document.body.innerHTML;
    – Ricky Apr 01 '13 at 09:39

10 Answers10

304

Using Javascript

var elemDiv = document.createElement('div');
elemDiv.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;';
document.body.appendChild(elemDiv);

Using jQuery

$('body').append('<div style="position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>');
Peter T.
  • 8,757
  • 3
  • 34
  • 32
  • 2
    strangest thing. at my worst, pure javascript has always been the way to do anything I wanted to do. – Spencer Williams Feb 21 '17 at 01:25
  • 5
    This should be the accepted answer. It is the only answer that goes about this in the correct way. – MacroMan Jul 17 '17 at 15:48
  • @MacroMan Even the jquery version? I'm using jquery and would like to do it properly that way too. (Just making sure because his jquery answer is only one line and doesn't seem to create a node or anything.) – felwithe Mar 21 '18 at 15:23
  • @felwithe The jQuery version is acceptable, but you may wish to create a node from scratch and apply the styles individually if you need more clarity in your code. – MacroMan Mar 22 '18 at 08:59
  • `appendChild()` and `insertBefore()` give even more flexibility on the location of the element to be inserted – averasko Jan 30 '20 at 18:18
215

Try this out:-

http://jsfiddle.net/adiioo7/vmfbA/

Use

document.body.innerHTML += '<div style="position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>';

instead of

document.body.innerHTML = '<div style="position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>';

Edit:- Ideally you should use body.appendChild method instead of changing the innerHTML

var elem = document.createElement('div');
elem.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000';
document.body.appendChild(elem);
Aditya Singh
  • 9,512
  • 5
  • 32
  • 55
  • 23
    You need to consider that doing document.body.innerHTML = 'something' incurs in a lot of unnecessary computation because the browser needs to parse the 'something' string and that takes a lot in a big page. A much more performant approach is to create the new element and attach it to the DOM. Check this comparision on jsperf: http://jsperf.com/innerhtml-vs-appendchild2 – fegemo Feb 11 '15 at 12:54
  • 17
    This approach will have some unwanted side effects as well. For example, all the bound events on child elements will become unbound once you set `innerHTML` afresh. – anoopelias Mar 09 '15 at 05:52
  • 5
    This is definitely the wrong answer... the question asks about adding an element, not rewriting the whole page, see JPH's for a better alternative. – Christian Mar 17 '17 at 22:57
  • 4
    -1. This is an awful way to achieve this. If you are reading this, do not use this slow and dated solution. Look at the answer by @peter-t – MacroMan Jul 17 '17 at 15:50
  • 3
    Not only is this slow, but destroys the earlier elements, so any event listeners attached to the page earlier are lost! Avoid doing this at all costs. Use appendChild instead. – Kranthi Kiran P Aug 13 '17 at 14:13
  • Despite using appenChild is the right way it seems innerHTML is faster. [comparison](https://image.ibb.co/byEEsy/Screenshot_186.png) Regardless of this result **do use appendChild**. – lowtechsun Jun 16 '18 at 08:24
  • @lowtechsun I'd imagine that gets slower as innerHTML gets bigger – Albert Renshaw Nov 17 '19 at 19:39
  • it is a wrong solution – ik00ma Dec 08 '21 at 13:42
23

Instead of replacing everything with innerHTML try:

document.body.appendChild(myExtraNode);

Joakim Poromaa Helger
  • 1,261
  • 10
  • 17
22

improving the post of @Peter T, by gathering all solutions together at one place.

Element.insertAdjacentHTML()

function myFunction() {
    window.document.body.insertAdjacentHTML( 'afterbegin', '<div id="myID" style="color:blue;"> With some data...</div>' );
}
function addElement(){
    var elemDiv = document.createElement('div');
    elemDiv.style.cssText = 'width:100%;height:10%;background:rgb(192,192,192);';
    elemDiv.innerHTML = 'Added element with some data'; 
    window.document.body.insertBefore(elemDiv, window.document.body.firstChild);
    // document.body.appendChild(elemDiv); // appends last of that element
}
function addCSS() {
    window.document.getElementsByTagName("style")[0].innerHTML += ".mycss {text-align:center}";
}

Using XPath find the position of the Element in the DOM Tree and insert the specified text at a specified position to an XPath_Element. try this code over browser console.

function insertHTML_ByXPath( xpath, position, newElement) {
    var element = document.evaluate(xpath, window.document, null, 9, null ).singleNodeValue;
    element.insertAdjacentHTML(position, newElement);
    element.style='border:3px solid orange';
}

var xpath_DOMElement = '//*[@id="answer-33669996"]';
var childHTML = '<div id="Yash">Hi My name is <B>\"YASHWANTH\"</B></div>';
var position = 'beforeend';
insertHTML_ByXPath(xpath_DOMElement, position, childHTML);
Yash
  • 9,250
  • 2
  • 69
  • 74
10

The most underrated method is insertAdjacentElement. You can literally add your HTML using one single line.

document.body.insertAdjacentElement('beforeend', html)

Read about it here - https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement

Vibhor Dube
  • 4,173
  • 1
  • 22
  • 32
8

The modern way is to use ParentNode.append(), like so:

let element = document.createElement('div');
element.style.cssText = 'position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;';
document.body.append(element);
Luís Ramalho
  • 10,018
  • 4
  • 52
  • 67
3

Try doing

document.body.innerHTML += '<div style="position:absolute;width:100%;height:100%;opacity:0.3;z-index:100;background:#000;"></div>'
3

You can make your div HTML code and set it directly into body(Or any element) with following code:

var divStr = '<div class="text-warning">Some html</div>';
document.getElementsByTagName('body')[0].innerHTML += divStr;
Yashar Aliabbasi
  • 2,663
  • 1
  • 23
  • 35
0

The best and better way is to create an element and append it to the body tag. Second way is to first get the innerHTML property of body and add code with it. For example:

var b = document.getElementsByTagName('body');
b.innerHTML = b.innerHTML + "Your code";
twernt
  • 20,271
  • 5
  • 32
  • 41
  • 3
    Firstly, you can get to the page body by simply doing `document.body`, secondly as I mentioned before, don't rewrite the whole page just to append an element. – Christian Mar 17 '17 at 22:57
-4

Here's a really quick trick: Let's say you wanna add p tag inside div tag.

<div>
<p><script>document.write(<variablename>)</script></p>
</div>

And that's it.

Poussy
  • 85
  • 4