How to maintain proper Javascript event after using cloneNode (true)

I have a form element that contains several lines of inputs. Think of each line as the attributes of a new object that I want to create in my web application. And I want to be able to create several new objects in one HTTP POST. I use the built-in cloneNode (true) Javascript method to clone each line. The problem is that each input line also has a delete link associated with its onclick event:

// prototype based <div class="input-line"> <input .../> <a href="#" onclick="$(this).up().remove();"> Remove </a> </div> 

When you click on the clone link of an input line, it also deletes any input lines that were cloned from the same dom object. Is it possible to restore the "this" object to the corresponding anchor tag after using the cloneNode (true) method in the above DOM element?

+4
source share
6 answers

Do not put a handler on every link (it really should be a button, BTW). Use the event bubble to handle all buttons with a single handler:

 formObject.onclick = function(e) { e=e||event; // IE sucks var target = e.target||e.srcElement; // and sucks again // target is the element that has been clicked if (target && target.className=='remove') { target.parentNode.parentNode.removeChild(target.parentNode); return false; // stop event from bubbling elsewhere } } 

+

 <div> <input…> <button type=button class=remove>Remove without JS handler!</button> </div> 
+7
source

You can try cloning using the innerHTML method or a combination:

 var newItem = $(item).cloneNode(false); newItem.innerHTML = $(item).innerHTML; 

Also: I think cloneNode does not clone events logged with addEventListener. But IE attachEvent events are cloned. But I could be wrong.

0
source

I tested this in IE7 and FF3 and it worked as expected - there must be something else going on.

Here is my test script:

 <div id="x"> <div class="input-line" id="y"> <input type="text"> <a href="#" onclick="$(this).up().remove();"> Remove </a> </div> </div> <script> $('x').appendChild($('y').cloneNode(true)); $('x').appendChild($('y').cloneNode(true)); $('x').appendChild($('y').cloneNode(true)); </script> 
0
source

To debug this problem, I would wrap your code

 $(this).up().remove() 

in function:

 function _debugRemoveInputLine(this) { debugger; $(this).up().remove(); } 

This will let you know what $ (this) returns. If it really returns more than one object (multiple lines), then you definitely know where to look - in the code that creates the element using cloneNode. Do you make any modification to the resulting element (i.e., changing the id attribute)?

If I have a problem that you are describing, I would consider adding unique identifiers to the launch element and the string element.

0
source

The first answer is correct.

Pornel implicitly offers the most cross-browser and frame agnostic solution.

Not tested, but the concept will work in these dynamic events-related situations.

0
source

Sounds like you're using jQuery? It has a method to clone an element with events: http://docs.jquery.com/Manipulation/clone#true

EDIT: Oh, I see you are using Prototype.

-1
source

Source: https://habr.com/ru/post/1276446/


All Articles