Reputation: 614
I am trying to make it so each child input added have the same event listener as the parent input.
Snippet (also on Codepen):
var main = document.getElementById("main").getElementsByTagName("a");
var button = document.createElement('input');
// Loop over A tags in #main
for (var i = 0; i < main.length; i++) {
// # of A tags
console.log(main.length);
// Event listener per # of A tags
main[i].addEventListener("click",function(e){
// Clone parentElement #main
var node = e.target.parentElement;
var clone = node.cloneNode(true);
// Append to DOM
document.getElementById('main').appendChild(clone);
});
}
<div id="main">
<div class="input__container">
<label>Input</label>
<input placeholder="Placeholder..." class="input" id="" name="" type="text"/>
<a class="btn">+</a>
</div>
</div>
Upvotes: 0
Views: 53
Reputation: 3883
I wouldn't say this is necessarily the best way to achieve this, but trying to stick with your general strategy here:
let cloneSelf = function(e) {
var parent = e.target.parentElement;
var clone = parent.cloneNode(true);
// Event listeners are not cloned with "cloneNode" so we have to do it manually.
clone.getElementsByTagName("a")[0].addEventListener("click", cloneSelf);
document.getElementById('main').appendChild(clone);
}
// Get the first link, and add the event listener
var firstLink = document.getElementById("main").getElementsByTagName("a")[0];
firstLink.addEventListener("click", cloneSelf);
<div id="main">
<div class="input__container">
<label>Input</label>
<input placeholder="Placeholder..." class="input" id="" name="" type="text" />
<a class="btn">+</a>
</div>
</div>
Upvotes: 0
Reputation: 1074178
You're not adding any a
elements to the DOM within your for
loop, so it stops when it's done with the ones within #main
that are there when it runs (there's only one).
You probably want to use event delegation on main
instead: You handle the click on main
, but then only do something with it if the click passed through an a.btn
; see comments:
// Get the element, not the `a` elements within it
var main = document.getElementById("main")
// Listen for clicks on it
main.addEventListener("click", function(e) {
// If this click passed through an `a.btn` within #main (this``)...
var btn = e.target.closest("a.btn");
if (btn && this.contains(btn)) {
// Clone the btn's parentElement, append to #main
var node = btn.parentElement;
var clone = node.cloneNode(true);
main.appendChild(clone);
}
});
<div id="main">
<div class="input__container">
<label>Input</label>
<!-- Note that `id` and `name` are not allowed to be blank; just leave them off -->
<input placeholder="Placeholder..." class="input" type="text"/>
<a class="btn">+</a>
</div>
</div>
Upvotes: 0
Reputation: 9
cloneNode method does not copy event listeners.
Cloning a node copies all of its attributes and their values, including intrinsic (in–line) listeners. It does not copy event listeners added using addEventListener() or those assigned to element properties (e.g. node.onclick = fn).
Upvotes: 0
Reputation: 51846
Instead of trying to duplicate the event handler, use a single delegated event handler attached to #main
:
var main = document.getElementById("main");
main.addEventListener("click", function(e) {
// Delegated event handler returning early if wrong target
if (!e.target.matches(".btn")) return;
// Clone parentElement .input__container
var node = e.target.parentElement;
var clone = node.cloneNode(true);
// Append to main
this.appendChild(clone);
});
<div id="main">
<div class="input__container">
<label>Input</label>
<input placeholder="Placeholder..." class="input" id="" name="" type="text" />
<a class="btn">+</a>
</div>
</div>
Upvotes: 2