Cloning elements

One more way that you can manipulate the DOM is to make copies of elements to attach elsewhere in the tree. jQuery provides a handy wrapper method for doing so with its clone() method.

Method syntax: clone
clone([copyHandlersAndData[, copyChildrenHandlersAndData]])
Creates a deep copy of the elements in the jQuery collection and returns a new jQuery collection that contains them. The elements and any children are copied. Event handlers and data are optionally copied depending on the setting of the copyHandlersAndData parameter.
Parameters
copyHandlersAndData(Boolean) If true, event handlers and data are copied. If false or omitted, handlers and data aren’t copied.
copyChildrenHandlersAndData(Boolean) If true, copies the event handlers and the data for all the children of the cloned elements. If omitted, if the first parameter is provided, the same value is used; otherwise false is assumed. If false, the event handlers and the data aren’t copied.
Returns
The newly created jQuery collection.

Making copies of existing elements with clone() isn’t useful unless you do something with the copies. Generally, once the set containing the clones is generated, another jQuery method is applied to stick them somewhere in the DOM. For example,

$('img').clone().appendTo('fieldset.photo');

makes copies of all img elements and appends them to all fieldset elements with the class name photo.

A slightly more interesting example is as follows:

$('ul').clone(true).insertBefore('#here');

This method’s chain performs a similar operation, but the targets of the cloning operation—all ul elements—are copied including their data and event handlers. In addition, because the clone() method clones children, too, and it’s likely that any ul element will have a number of li children, you’re sure that no information is lost. Because you omit the second argument but specify the first, the data and event handlers of all the children are also copied.

Before moving to another topic, let’s discuss one last example. Imagine that you have a set of links with an image inside them. Both links and images have some data and events handlers attached. You want to copy all of them and place the copies after all the elements inside the first div of the page. In addition, you want to retain only the data and the handlers of the links, not those of the images inside. This task is performed with the following statement:

$('a').clone(true, false).appendTo('div:first');

This statement shows you the use of the optional parameters discussed in the description of the method.

In order to see the clone operation in action, return to the Move and Copy Lab Page. Just above the Execute button is a pair of radio buttons that allows you to specify a cloning operation as part of the main DOM manipulation operation. When the Yes radio button is selected, the sources are cloned before the append()prepend()before(), and after() methods are executed.

Repeat some of the experiments you conducted earlier with cloning enabled, and note how the original sources are unaffected by the operations.

You can insert, remove, and copy. Using these operations in combination, it would be easy to perform higher-level operations such as replace. But guess what? You don’t need to!

Replacing elements

For those times when you want to replace existing elements with new ones, or to move an existing element to replace another, jQuery provides the replaceWith() method.

Method syntax: replaceWith
replaceWith(content)
Replaces each matched element with the specific content.
Parameters
content(String|Element|Array|jQuery|Function) A string containing an HTML fragment to become the replaced content, or a DOM element, an array of DOM elements, or a jQuery object containing the elements to be moved to replace the existing elements. If a function, the function is invoked for each element in the set, setting that element as the function context (this) and passing no parameters. The function’s returned value is used as the new content.
Returns
A jQuery collection containing the replaced elements.

To understand what this method does, let’s discuss an example. Imagine that you have the following markup:

<img src="image1.jpg" alt="A ball" />
<img src="image2.jpg" alt="A blue bird" />
<img src="image3.jpg" />

You want to replace all the images that have an alt attribute, one at a time, with span elements. The latter will have as their text the value of the alt attribute of the image being replaced. Employing each() and replaceWith(), you could do it like this:

$('img[alt]').each(function(){
  $(this).replaceWith('<span>' + $(this).attr('alt') + '</span>');
});

The each() method lets you iterate over each matched element, and replaceWith() is used to replace the images with generated span elements. The resulting markup is shown here:

<span>A ball</span>
<span>A blue bird</span>
<img src="image3.jpg" />

This example shows once again how easy it is to work with jQuery to manipulate the DOM.

The replaceWith() method returns a jQuery set containing the elements that were removed from the DOM, in case you want to do something other than just discard them. As an exercise, consider how you’d augment the example code to reattach these elements elsewhere in the DOM after their removal.

When an existing element is passed as the argument to replaceWith(), it’s detached from its original location in the DOM and reattached to replace the target elements. If there are multiple such targets, the original element is cloned as many times as needed.

At times, it may be convenient to reverse the order of the elements as specified by replaceWith() so that the replacing element can be specified using the matching selector. You’ve already seen such complementary methods, such as append() and appendTo(), that let you specify the elements in the order that makes the most sense for your code.

Similarly, the replaceAll() method mirrors replaceWith(), allowing you to perform a similar operation. But in this case the elements to be replaced are defined by the selector passed as arguments and thus are not those the method is called upon.

Method syntax: replaceAll
replaceAll(target)
Replaces each element matched by the passed target with the set of matched elements to which this method is applied
Parameters
target(String|Element|Array|jQuery) A selector string expression, a DOM element, an array of DOM elements, or a jQuery collection that specifies the elements to be replaced
Returns
A jQuery collection containing the inserted elements

Like replaceWith()replaceAll() returns a jQuery collection. But it doesn’t contain the replaced elements but rather the replacing elements. The replaced elements are lost and can’t be further operated upon. Keep this in mind when deciding which replace method to employ.

Based on the description of the replaceAll() method, you can achieve the same goal of the previous example by writing the following:

$('img[alt]').each(function(){
  $('<span>' + $(this).attr('alt') + '</span>').replaceAll(this);
});

Note how you invert the argument passed to $() and replaceAll().

Now that we’ve discussed handling general DOM elements, let’s take a brief look at handling a special type of element: the form elements.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *