Reputation: 61
I cannot find the error in my code. This is supposed to be a simple clone and remove script. I am trying to convert it from a Jquery script, but no luck so far.
document.querySelector(".wrapper").addEventListener("click", ".remove", function() {
document.querySelector(".remove")
.closest(".wrapper")
.querySelector(".element")
.not(":first")
.last()
.remove();
});
document.querySelector(".wrapper").addEventListener("click", ".clone", function() {
document.querySelector(".clone")
.closest(".wrapper")
.querySelector(".element")
.first()
.clone()
.appendTo(".results");
});
body {
padding: 1em;
}
.element {
background: #eee;
width: 200px;
height: 40px;
padding: 20px 20px 0;
text-align: center;
margin: 5px 0;
}
.buttons {
clear: both;
margin-top: 10px;
}
<div class="wrapper">
<div class="element"></div>
<div class="results"></div>
<div class="buttons">
<button class="clone">clone</button>
<button class="remove">remove</button>
</div>
</div>
Upvotes: 0
Views: 126
Reputation: 12920
There are a number of problems with you code, but the main error is that you are passing the wrong arguments to addEventListener
whose syntax is target.addEventListener(type, listener [, options]);
where type
is the event type and listener
is a callback function. The callback will be passed the event object intrinsically.
Since you are attaching the listener to the wrapper
element, you need to evaluate the event.target
when triggered to determine which button was actually clicked.
if (event.target.classList.contains('clone')) {...
You can then call the necessary function based on this evalution passing either the entire event object, or in the example below, just the element returned by event.target
.
Next, while chaining will get you a long way, it is actually advantageous here to declare some variables to avoid multiple queries to the same element.
A few smaller things :
It isn't necessary to check for first
as querySelector
only returns the first element that matches.
Likewise, specifying not(:first)
won't stop querySelector
as it only returns the first.
In order to access the last element, you can simply get them all using querySelectorAll
and retrieve the last element from the returned NodeList. (destructured to an array here)
[...allElements][allElements.length-1].remove();
function clone(button) {
const wrapper = button.closest(".wrapper");
const cloneElement = wrapper.querySelector(".element").cloneNode(true);
wrapper.querySelector(".results").appendChild(cloneElement);
}
function remove(button) {
const allElements = button.closest(".wrapper").querySelectorAll(".element");
if (allElements.length >1) [...allElements][allElements.length-1].remove();
}
document.querySelector(".wrapper").addEventListener("click", function (event) {
if (event.target.classList.contains('clone')) {
clone(event.target);
} else if (event.target.classList.contains('remove')) {
remove(event.target);
}
});
body {
padding: 1em;
}
.element {
background: #eee;
width: 200px;
height: 40px;
padding: 20px 20px 0;
text-align: center;
margin: 5px 0;
}
.results .element {
background-color: aquamarine;
}
.buttons {
clear: both;
margin-top: 10px;
}
<div class="wrapper">
<div class="element">
Element
</div>
<div class="results"></div>
<div class="buttons">
<button class="clone">clone</button>
<button class="remove">remove</button>
</div>
</div>
Upvotes: 1