How does the cloneNode method work?

Asked

Viewed 138 times

2

I am creating an application and need to copy an element to create it again in the HTML page. Searching the internet, I found the method cloneNode. I want to know the following:

  • How the method works?
  • Does it copy only the object style or its events as well? How deep is cloning?
  • There is a parameter to only copy styles and attributes, but discarding any event?

1 answer

2


Basically, cloneNode copies the Node, but the clone doesn’t have one Parent and will not be part of the document unless you add it somewhere.

It takes a parameter boolean indicating whether the copy should be deep or not.

In case of copy no-deep, only the Node and its attributes are copied. Not even the text that is inside the tag is copied. In the case of events, only those defined inline will be copied. Already those added by addEventListener not evening.

If the copy is deep, all child nodes are copied. But events added by addEventListener will continue not to be copied.

Example:

document.querySelector('#paragrafo').addEventListener('click', function() {
    alert('cliquei no paragrafo');
});

function clonar(deep) {
    let clone = document.querySelector('#paragrafo').cloneNode(deep);
    // remover o id, senão você terá mais de um elemento com o mesmo id
    clone.removeAttribute('id');
    document.querySelector('#main').appendChild(clone);
}
p {
    padding: 2px;
    color: blue;
    border: 1px solid blue;
}

#paragrafo {
    color: red;
    border: 1px solid red;
}
<div id="main">
  <p id="paragrafo" onclick="alert(`inline onclick ${this.id}`)">lorem <b>ipsum</b> etc</p>
</div>

<form>
  <input name="deep" type="checkbox">Deep clone<br>
  <input type="button" value="clonar parágrafo" onclick="clonar(this.form.deep.checked)">
</form>

I put a border around the paragraphs so that it is possible to view in the cases of copies not-deep, since in such cases the paragraph will not have any text (only the empty tag). But note that the clones still keep the event defined by onclick (but it doesn’t have what was defined by addEventListener).


Another detail cited in the documentation is that the value default of the parameter deep, when not specified, may vary according to implementation (in older versions of some browsers era true, but in the newer specifications it became false). Therefore the most guaranteed is always pass the parameter according to what you need.


About the styles, in the examples I used I had no problems, but researching I found this question saying that the computed Styles were not copied. If this is your case, the solution lies in the answers from there.

  • Thanks for the reply. But then how can I copy an element completely? I mean, having two identical objects, in style, texts, child elements and events (including listeners) but being different in memory?

  • @Jeanextreme002 From what I’ve researched, natively can not copy all Event listeners (some suggest to store this somewhere and then add manually, or use jQuery, which uses a separate mechanism to clone and can copy the listeners). And just remember that by cloning with cloneNode, clone is already a "different object in memory" :-)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.