Manipulating the DOM

Contact Us or call 1-877-932-8228
Manipulating the DOM

Manipulating the DOM

Once you've made a selection, the fun begins. You can change, move, remove, and clone elements. You can also create new elements via a simple syntax.

For complete documentation of jQuery manipulation methods, visit http://api.jquery.com/category/manipulation/.

Moving, Copying, and Removing Elements

There are a variety of ways to move elements around the DOM; generally, there are two approaches:

  • Place the selected element(s) relative to another element
  • Place an element relative to the selected element(s)

For example, jQuery provides $.fn.insertAfter and $.fn.after. The $.fn.insertAfter method places the selected element(s) after the element that you provide as an argument; the$.fn.after method places the element provided as an argument after the selected element. Several other methods follow this pattern: $.fn.insertBefore and $.fn.before; $.fn.appendTo and $.fn.append; and $.fn.prependTo and $.fn.prepend.

As a way to remember which is which, consider the following. Assuming that $newItem is the item we are placing into the page, and $destination is the element relative to which we are placing $newItem:

$newItem.appendTo($destination);
$newItem.prependTo($destination);
$newItem.insertBefore($destination);
$newItem.insertAfter($destination);

$destination.append($newItem);
$destination.prepend($newItem);
$destination.before($newItem);
$destination.after($newItem);

The method that makes the most sense for you will depend on what elements you already have selected, and whether you will need to store a reference to the elements you're adding to the page. If you need to store a reference, you will generally want to take the first approach -- placing the selected elements relative to another element -- as it returns the element(s) you're placing. In this case, $.fn.insertAfter, $.fn.insertBefore, $.fn.appendTo, and $.fn.prependTo will be your tools of choice.

Moving Elements Using Different Approaches

Code Sample:

jqy-concepts/Demos/moving-elements.html
---- C O D E   O M I T T E D ----
<script>
$(document).ready(function() {
// make the first list item the last list item
$('#myList li:first').appendTo('#myList').addClass('current');

// another approach to the same problem
$('#myList').append($('#myList li:first')).addClass('italic');

// note that there's no way to access the
// list item that we moved, as this returns
// the list itself
});
</script>

---- C O D E   O M I T T E D ----
</html>

Cloning Elements

When you use methods such as $.fn.appendTo, you are moving the element; sometimes you want to make a copy of the element instead. In this case, you'll need to use $.fn.clone first. The clone method is overloaded -- with no parameters, it makes a shallow clone, which does not clone event handlers and data (jQuery has a facility for associating data with an element, which we will cover later). If a true value is passed as a parameter, event handlers and data are cloned as well.

Note: ids will get cloned as well as other attributes, but you shouldn't have two page elements with the same id. So, after cloning an element with an id, you should either remove the id or set it to some unique value, before inserting it into the document.

$('#myDiv')
	.clone().removeAttr('id')
	.appendTo('body');

// or

$('#myDiv')
	.clone().attr('id', 'newId_1')
	.appendTo('body');

Making a Copy of an Element

// copy the first list item to the end of the list
$('#myList li:first').clone().appendTo('#myList');

Removing Elements

There are two ways to remove elements from the page: $.fn.remove and $.fn.detach. You'll use $.fn.remove when you want to permanently remove the selection from the page; while the method does return the removed element(s), those elements will not have their associated data and events attached to them if you return them to the page.

If you need the data and events to persist, you'll want to use $.fn.detach instead. Like $.fn.remove, it returns the selection, but it also maintains the data and events associated with the selection, so you can restore the selection to the page at a later time.

Note: The $.fn.detach method is extremely valuable if you are doing heavy manipulation to an element. In that case, it's beneficial to $.fn.detach the element from the page, work on it in your code, and then restore it to the page when you're done. This saves you from expensive "DOM touches" while maintaining the element's data and events.

If you want to leave the element on the page but simply want to remove its contents, you can use $.fn.empty to dispose of the element's inner HTML.

Creating New Elements

jQuery offers a trivial and elegant way to create new elements using the same $() method you use to make selections.

Creating New Elements

If you create a string of text with the HTML for an element, then pass it to $(), a DOM element will be created. The method returns a single-element collection containing the new element. You can then use any of the methods discussed earlier to add it to the document.

You can also pass an HTML string to any of the methods that accept an element to insert into the DOM.

$('<p>This is a new paragraph!</p>').prependTo($('body'));
$('<li class="new">new list item</li>').appendTo($('#myList'));

$('body').append('<p>This is another new paragraph!</p>');

The above approaches will also work if you use a selector for the destination, instead of a jQuery object. The difference in the code below is that the parameters to appendTo and prependTo are simple strings, instead of return values from the $ function.

$('<p>This is a new paragraph!</p>').prependTo('body');
$('<li class="new">new list item</li>').appendTo('#myList');

You can pass a second parameter with options representing body content and attributes for the tag.

$('<a/>', {
	html : 'This is a <em>new</em> link',
	'class' : 'new',
	href : 'foo.html'
}).appendTo($('body'));

Note that the 'class' property of the element attributes object is quoted -- this is to avoid conflicts with the reserved word class.

Also note the empty <a /> tag -- it gets populated by the html property of the second parameter.

It is worth noting that this approach of creating an element with an attributes object only works when the HTML and attributes are passed to the $ function. You cannot pass both an HTML string and an attributes object to the methods like append. For string parameters, it will only accept a single parameter with the HTML string, or a series of strings, each representing an element to create and add. But, you could instead pass it a jQuery object, including one you created from a string.

// Won't work
$('#myDiv')
	.append('<h2/>', { html: 'New Heading', 'class': 'yellowBg' });

// Will work
$('#myDiv')
	.append($('<h2/>', { html: 'New Heading', 'class': 'yellowBg' }));

Code Sample:

jqy-concepts/Demos/creating-new-elements.html
---- C O D E   O M I T T E D ----
<script>
$(document).ready(function() {
	// simple elements
	$('<p>A new paragraph!</p><p>Another new paragraph!</p>')
		.prependTo($('body'));
	$('<li class="new">new list item</li>').appendTo($('#myList'));
	$('body').append('<p>This is another new paragraph!</p>');	
	
	// element with attributes object
	$('<a/>', { 
		html : 'This is a <em>new</em> link',
		'class' : 'new',
		href : 'foo.html'
	}).appendTo($('body'));
});
</script>
</head>
<body>
<ul id="myList">
	<li>First</li>
	<li>Second</li>
	<li>Third</li>
	<li>Fourth</li>
</ul>
<hr />
</body>
</html>

The syntax for adding new elements to the page is so easy, it's tempting to forget that there's a huge performance cost for adding to the DOM repeatedly. If you are adding many elements to the same container, you'll want to concatenate all the HTML into a single string, and then append that string to the container instead of appending the elements one at a time. You can use an array to gather all the pieces together, then join them into a single string for appending.

var myItems = [], $myList = $('#myList');

for (var i=0; i<100; i++) {
	myItems.push('<li>item ' + i + '</li>');
}

$myList.append(myItems.join(''));
Next