jQuery 3 - Creating & Modifying The DOM
Written by Ian Elliot   
Monday, 31 October 2016
Article Index
jQuery 3 - Creating & Modifying The DOM
Move and Copy
Inserting, Replacing & Removing
Building a Dynamic Table

justjquery

Moving and Cloning

Now we come to a subtle point that often confuses the beginner. If there is an array of elements to be appended or prepended to then a copy of the dom object is added to each one. For example:

$("div").append(divObj);

will append a copy of the divObj to each of the div elements in the document. 

This might lead you to belive that you can do something like:

$("#mydiv1").append(divObj);
$("#mydiv2").append(divObj);

and expect to find divObj appended to each of the divs.

This isn't the case.

What happens is that you will find divObj appended only to the final div, i.e. mydiv2.

When you append to an array of objects a copy of the object being appended is automatically created. When you append an object more than once a copy isn't created and the original object is just relocated i.e. moved.

You can use this technique to move nodes around the DOM. For example:

$("#mydiv2").append($(#mydiv1));

moves #mydiv1 to be a child of #mydiv2. 

Suppose you actually want to append lots of copies of the same DOM object - how do you do this?

The solution is to use the clone method which makes a complete copy of any jQuery object - or any object for that matter.

So to add two copies of divObj one to each div you would use:

$("#div1").append(divObj.clone()); $("#div2").append(divObj.clone());

Similarly if you want to copy an object from one place to another rather than move it then simply clone it first. For example:

$("#mydiv2").append($(#mydiv1).clone());

which of course results in two copies of #mydiv1 and hence two elements with the same id - not a good idea.

It is important to realize the the clone method creates a deep clone i.e. it clones all object that are within the top level object. However you do have some control over how deep the clone is. If you specify 

.clone(true);

then the copy includes event handlers and element data of the top level object. 

If you specify

.clone(true,true);

then it includes the event handlers and element data of the top level object and its children.  

Inserting As A Parent Element

Most of the time you want to append or prepend an element to the DOM you are creating. The reason is simply that if you are creating a DOM in code you usually build it up from the top down. However sometimes you want to add your new element so that it contains an existing node.  This can be thought of as wrapping an element in a new parent element. 

For example, wrap(element) will take each element in the results list, place it inside the specified element as a child and then replace the element in the DOM.

For example

$("#mydiv2").wrap($("<div>");

puts a div around the existing div with id=mydiv2. That is it changes

<div id=mydiv2>
 ...
</div>

into

<div>
 <div id=mydiv2>
   ...
 </div>
</div>

You can see that the method is well named and you can think of it as wrapping each of the matched elements in the new element. You can wrap a list of elements in a deeply nested DOM structure but notice that to make the place where the existing element is moved unique there can only be one innermost slement. For example, if you try to wrap 

<div>
 <div>
 </div>
 <div>
 </div>
</div>

around a list of elements there are two inner divs and which one is used to host the existing element? In practice jQuery wraps the existing element in the first of the inner element i.e. the first inner div. 

If you try to wrap a list of elements then each one will be wrapped by the DOM structure you sepecifiy. For example if you have

<div>
 <div> </div>
 <div> </div>
</div>

Then

 

$("div").wrap("<p>");

changes the DOM to:

 

<p>
 <div>
  <p>
   <div>  </div>
  </p>
  <p>
   <div></div>
  </p>
 </div>
</p>

That is it wraps every <div> with a <p>. 

The wrapAll method doesn't wrap each result with its own clone of the sepecified element. Instead it wraps all of the results by a single element. So the same HTML in the previsou example is transformed by

$("div").wrap("<p>");

into

<p>
 <div>
     <div></div>
     <div></div>
  </div>
</p>

You can see that now that all of the divs are wrapped by a single <p>. WrapAll is a difficult method to use. The reason is that what it does is slightly strange. It takes all of the elements in the result and removes them from the DOM. wraps them in the structure supplied and then inserts them a the position of the first element in the result. 

For example consider the DOM generated by

<div>
 test0
</div>
<p>test1</p>
<div>
 <p>test2</p>
</div>

If you use

$("div").wrapAll("<p class=wrapper");

the result is:

<p class="wrapper">
 <div>
   test0
   </div><div>
   <p>test2</p>
 </div>
</p>
<p>test1</p>

Notice that the paragraph <p>test1</p> has been left behind. All of the extracted divs have been removed, wrapped and inserted in place of the first div. 

There is one final variation on the wrap method - wrapInner. This works in much the same way but now it wraps the content of each element in the results. As before the content of an element can be best be thought of as what you would find between the opening and closing tags. If we use:

$("div").wrapinner("<p class="wrapper"");

on the previous example DOM we get:
<div>
 <p class="wrapper">
   test0
 </p>
</div>
<p>test1</p>
<div>
 <p class="wrapper">
   <p>test2</p>
 </p>
</div>

You can see that what is between the div tags has indeed been wrapped by the paragraph object.



Last Updated ( Wednesday, 30 November 2016 )