Pure javascript method to wrap content in a div

JavascriptHtml

Javascript Problem Overview


I want to wrap all the nodes within the #slidesContainer div with JavaScript. I know it is easily done in jQuery, but I am interested in knowing how to do it with pure JS.

Here is the code:

<div id="slidesContainer">
    <div class="slide">slide 1</div>
    <div class="slide">slide 2</div>
    <div class="slide">slide 3</div>
    <div class="slide">slide 4</div>
</div>

I want to wrap the divs with a class of "slide" collectively within another div with id="slideInner".

Javascript Solutions


Solution 1 - Javascript

If your "slide"s are always in slidesContainer you could do this

org_html = document.getElementById("slidesContainer").innerHTML;
new_html = "<div id='slidesInner'>" + org_html + "</div>";
document.getElementById("slidesContainer").innerHTML = new_html;

Solution 2 - Javascript

Like BosWorth99, I also like to manipulate the dom elements directly, this helps maintain all of the node's attributes. However, I wanted to maintain the position of the element in the dom and not just append the end incase there were siblings. Here is what I did.

var wrap = function (toWrap, wrapper) {
    wrapper = wrapper || document.createElement('div');
    toWrap.parentNode.appendChild(wrapper);
    return wrapper.appendChild(toWrap);
};

Solution 3 - Javascript

How to "wrap content" and "preserve binded events" ?

// element that will be wrapped
var el = document.querySelector('div.wrap_me');
// create wrapper container
var wrapper = document.createElement('div');
// insert wrapper before el in the DOM tree
el.parentNode.insertBefore(wrapper, el);
// move el into wrapper
wrapper.appendChild(el);

or

function wrap(el, wrapper) {
    el.parentNode.insertBefore(wrapper, el);
    wrapper.appendChild(el);
}
// example: wrapping an anchor with class "wrap_me" into a new div element
wrap(document.querySelector('div.wrap_me'), document.createElement('div'));

ref

https://plainjs.com/javascript/manipulation/wrap-an-html-structure-around-an-element-28

Solution 4 - Javascript

If you patch up document.getElementsByClassName for IE, you can do something like:

var addedToDocument = false;
var wrapper = document.createElement("div");
wrapper.id = "slideInner";
var nodesToWrap = document.getElementsByClassName("slide");
for (var index = 0; index < nodesToWrap.length; index++) {
    var node = nodesToWrap[index];
    if (! addedToDocument) {
        node.parentNode.insertBefore(wrapper, node);
        addedToDocument = true;
    }
    node.parentNode.removeChild(node);
    wrapper.appendChild(node);
}

Example: http://jsfiddle.net/GkEVm/2/

Solution 5 - Javascript

I like to manipulate dom elements directly - createElement, appendChild, removeChild etc. as opposed to the injection of strings as element.innerHTML. That strategy does work, but I think the native browser methods are more direct. Additionally, they returns a new node's value, saving you from another unnecessary getElementById call.

This is really simple, and would need to be attached to some type of event to make any use of.

wrap();
function wrap() {
    var newDiv = document.createElement('div');
    newDiv.setAttribute("id", "slideInner");
    document.getElementById('wrapper').appendChild(newDiv);
    newDiv.appendChild(document.getElementById('slides'));
}

jsFiddle

Maybe that helps your understanding of this issue with vanilla js.

Solution 6 - Javascript

To simply wrap a div without the need of the parent:

<div id="original">ORIGINAL</div>

<script>

document.getElementById('original').outerHTML
=
'<div id="wrap">'+
document.getElementById('original').outerHTML
+'</div>'

</script>

Working Example: https://jsfiddle.net/0v5eLo29/

More Practical Way:

const origEle = document.getElementById('original');
origEle.outerHTML = '<div id="wrap">' + origEle.outerHTML + '</div>';

Or by using only nodes:

let original = document.getElementById('original');
let wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.append(original.cloneNode(true));

original.replaceWith(wrapper);

Working Example: https://jsfiddle.net/wfhqak2t/

Solution 7 - Javascript

A general good tip for trying to do something you'd normally do with jQuery, without jQuery, is to look at the jQuery source. What do they do? Well, they grab all the children, append them to a a new node, then append that node inside the parent.

Here's a simple little method to do precisely that:

const wrapAll = (target, wrapper = document.createElement('div')) => {
  ;[ ...target.childNodes ].forEach(child => wrapper.appendChild(child))
  target.appendChild(wrapper)
  return wrapper
}

And here's how you use it:

// wraps everything in a div named 'wrapper'
const wrapper = wrapAll(document.body) 

// wraps all the children of #some-list in a new ul tag
const newList = wrapAll(document.getElementById('some-list'), document.createElement('ul'))

Solution 8 - Javascript

A simple way to do this would be:

let el = document.getElementById('slidesContainer');
el.innerHTML = `<div id='slideInner'>${el.innerHTML}</div>`;

Solution 9 - Javascript

From what I understand @Michal 's answer is vulnerable to XXS attacks (using innerHTML is a security vulnerability) Here is another link on this.

There are many ways to do this, one that I found and liked is:

function wrap_single(el, wrapper) {
    el.parentNode.insertBefore(wrapper, el);
    wrapper.appendChild(el);
}
let divWrapper;
let elementToWrap;
elementToWrap = document.querySelector('selector');
// wrapping the event form in a row
divWrapper = document.createElement('div');
divWrapper.className = 'row';
wrap_single(elementToWrap, divWrapper);

This works well. However for me, I sometimes want to just wrap parts of an element. So I modified the function to this:

function wrap_some_children(el, wrapper, counter) {
  el.parentNode.insertBefore(wrapper, el);
  if ( ! counter ) {
    counter = el.childNodes.length;
  }
  for(i = 0; i < counter;  i++) {
    wrapper.appendChild( el.childNodes[0] );
  }
}
// wrapping parts of the event form into columns
let divCol1;
let divCol2;
// the elements to wrap
elementToWrap = document.querySelector('selector');
// creating elements to wrap with
divCol1 = document.createElement('div');
divCol1.className = 'col-sm-6';
divCol2 = document.createElement('div');
divCol2.className = 'col-sm-6';
// for the first column
wrap_some_children(elementToWrap, divCol1, 13);  // only wraps the first 13 child nodes
// for the second column
wrap_some_children(elementToWrap, divCol2);

I hope this helps.

Solution 10 - Javascript

wrapInner multiple tag content


function wilWrapInner(el, wrapInner) {
  var _el = [].slice.call(el.children);
  var fragment = document.createDocumentFragment();
  el.insertAdjacentHTML('afterbegin', wrapInner);
  var _wrap = el.children[0];
  for (var i = 0, len = _el.length; i < len; i++) {
    fragment.appendChild(_el[i]);
  }
  _wrap.appendChild(fragment);
}

Link Demo Jsbin

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSquadronsView Question on Stackoverflow
Solution 1 - JavascriptMichalView Answer on Stackoverflow
Solution 2 - Javascriptuser1767210View Answer on Stackoverflow
Solution 3 - JavascriptBGBRUNOView Answer on Stackoverflow
Solution 4 - JavascriptarothView Answer on Stackoverflow
Solution 5 - JavascriptBosworth99View Answer on Stackoverflow
Solution 6 - JavascriptproseosocView Answer on Stackoverflow
Solution 7 - JavascriptAnsiktView Answer on Stackoverflow
Solution 8 - JavascriptErshad QaderiView Answer on Stackoverflow
Solution 9 - JavascriptWillView Answer on Stackoverflow
Solution 10 - Javascriptviet namView Answer on Stackoverflow