0

i don't want to use this method because if there's multiple elements with same id they will all be removed i need a method to only delete the parent element of the button that was clicked. Because if you execute this code and click the button it will delete all elements with the id of "div-list" but i only want it to delete the parent element of only the button that clicked it

let button = document.getElementById('button-submit');
let div = document.getElementById('div-list');
div.appendChild(button);
button.onclick = () => {
    div.remove();
}

i found a way that works but i want another one that is only javascript here's the method that works but i hope there's another way to do it:

<div>
<button onclick="this.parentElement.remove()"></button>
<div>
Ninja MB7
  • 3
  • 1
  • ```multiple elements with same id```??? No, ID is unique. You can't assign or a single page can not contain multiple elements with the same ID. – Md. Rakibul Islam Jul 30 '23 at 14:38

5 Answers5

0

All DOM elements in javascript have the .parentElement property. This means that in the button.onClick function you can simply say: button.parentElement.remove(); Thus removing only the parent.

Nicholas
  • 41
  • 9
0

There shouldn't be multiple html-tags with the same id (as described here for example). You could use this:

let button = document.getElementById('button-submit');

button.onclick = button.parentElement.remove;

If you want to assign the function to more than one button, consider using classnames instead of an id. The removed element will still only be the parent element of the clicked button.

Note that there is more than one way to achieve what you want and each way has pros and cons as seen in other existing answers.

kzi
  • 186
  • 1
  • 8
  • @moken Thanks for the tip, I've added to my answer. If you have any suggestions for improvement, please let me know. – kzi Jul 31 '23 at 07:42
  • Your answer was flagged (not by me) as "low quality" so potentially could have been deleted. By adding some additional detail to explain how your answer helps does three things; 1) The more explanatory your answer the better for all viewing it. Remember it's not just the poster of the orig question that may be helped. 2) The edit removes the answer from the "low quality" queue and it will not longer be voted on for deletion. If you check the "show activity for this post" you will see the "low quality" review has been invalidated. 3) Your answer is unlikely to be flagged again in future. – moken Jul 31 '23 at 08:05
0

An event listener receives an event as the first argument. That event has currentTarget as a property, which points to the element to which the event handler is attached (in your case the button).

And for that element you can use the parentElement:

function removeParent(event) {
  event.currentTarget.parentElement.remove();
}

document.querySelector('#btn1').onclick = removeParent
document.querySelector('#btn2').onclick = removeParent
<div>
<button id="btn1"></button>
</div>

<div>
<button id="btn2"></button>
<div>

As a note: You should not use the on... properties to attach events, instead use addEventListener:

function removeParent(event) {
  event.currentTarget.parentElement.remove();
}

document.querySelector('#btn1').addEventListener('click', removeParent)
document.querySelector('#btn2').addEventListener('click', removeParent)
<div>
<button id="btn1"></button>
</div>

<div>
<button id="btn2"></button>
<div>

With the on... properties, you can only attach one event handler of a particular event to an element, which can result in hard-to-debug problems in a larger code base when you accidentally overwrite an event handler that still should exist on the element.

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • `this.parentElement.remove();` can be used instead. – Unmitigated Jul 30 '23 at 14:43
  • @Unmitigated That is true, but with `event.currentTarget` you will always get the element to which the event handler was attached to. With `this` this is not necessarily the case. E.g. if one is using an arrow function, which can be quite handy if you want to use class functions as event listeners, because arrow functions as class fields bind automatically to the `this` of the class ([Arrow function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions): `Because a class's body has a this context, ...`) – t.niese Jul 30 '23 at 14:52
  • Yes, I'm aware of that. I'm only pointing that out here because regular functions are used. – Unmitigated Jul 30 '23 at 15:05
0

Using ID's is not really ideal.

When you have multiple Elements you want to do the same too, it's usually better to use something called delegated events.

This works by adding your click handler onto a parent element .items and then checking the target to see if it's the element your after .remove , you can then find the parent .item of this element and remove.

A bonus to this approach is if you later dynamically add items, the events will work for them also. Also notice in the example below I've used closest, the advantage to parentElement is that it will continue to work if you alter the layout later.

Below is a simple example..

document.querySelector('.items')
  .addEventListener('click', e => {
     if(e.target.classList.contains('remove')) {
       e.target.closest('.item').remove();
     }
  });
<div class="items">

  <div class="item">
    Item 1
    <button class="remove">Remove</button>
  </div>

  <div class="item">
    Item 2
    <button class="remove">Remove</button>
  </div>

  <div class="item">
    Item 3
    <button class="remove">Remove</button>
  </div>

  <div class="item">
    Item 4
    <button class="remove">Remove</button>
  </div>

</div>
Keith
  • 22,005
  • 2
  • 27
  • 44
  • "Using ID's is not really ideal." Why? Let's suppose that I want to be able to uniquely identify an element, knowing that the identifier I assign to it will not be used by other elements. Like, having an id of `element-223` and for other element, to have an id of `element-345`, never duplicating it. So, when I want to update some content of an element, I know that the context to tackle with is inside element-. Why do you claim that it's wrong to do it? – Lajos Arpad Jul 30 '23 at 15:09
  • @LajosArpad Unless your using it for anchor tag navigating, I would avoid. If you just want to uniquely identify an element a data attribute would be way better. `data-id='xyz'` ID's have been abused like this for years, not only is there better options, you end up getting window globals with all these ID's. – Keith Jul 30 '23 at 15:16
  • I will not end up having such abuses. I'm a seasoned programmer and will not make that mistake. Nor my teammates. And, if someone makes such a mistake, an HTML validator will automatically detect it. Or a fellow programmer during a pull request. But you say "Unless your using it for anchor tag navigating, I would avoid". Do you have any objective reason to avoid it beyond the fear of ids being abused? – Lajos Arpad Jul 30 '23 at 15:18
  • @LajosArpad Yes, I just told you. All the window global ID's. Might not bother you, but having all the window global's just doesn't sit right with me.. – Keith Jul 30 '23 at 15:22
  • Okay, so you have a subjective preference for the avoidance of using ids so that they will not be abused. – Lajos Arpad Jul 30 '23 at 15:27
0

First, let's test your theory

for (let item of document.getElementById("foo").querySelectorAll("input")) item.addEventListener("click", function() {
    this.parentNode.remove();
});
<div id="foo"><input type="button" value="first button"></div>
<div id="foo"><input type="button" value="second button"></div>

As we can see, an event is attached to the very first input inside the element of the given id and its parent will be removed. Which brings us to a very important point to make:

Duplication of ids is invalid in HTML and should be avoided whenever possible

So, convert your button-submit and div-list ids to classes and do the following:

for (let button of document.getElementsByClassName("button-submit")) {
    button.addEventListener("click", function() {
        button.parentNode.remove();
    });
}

I ignored adding your buttons into your divs for now, because you have given us no contextual information about the structure that you have.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Although I don't advocate duplicated ID's, in fact I don't advocate ID's full stop, unless it's for anchor tag navigating. Multiple ID's do work and are valid in HTML, it's just that `getElementById` intrinsically only returns a single item. So you just don't use that, so in your example -> `for (let item of document.querySelectorAll("#foo input"))` will work. Of course duplicate ID's for anchor tag navigating, (what it was designed for), would make no sense at all... – Keith Jul 30 '23 at 14:56
  • @Keith let's differentiate between "works" and "valid". Yes, I'm aware that you can select ids as attributes, but I did not advocate that, to avoid supporting id duplication. It **is** invalid to duplicate ids, because it goes against the spec (see https://stackoverflow.com/questions/48240240/why-are-duplicate-id-values-not-allowed-in-html). Yet, there is nothing wrong in using ids in HTML as long as one does not duplicate them. id means identifier. If it's not unique, then it's unspecific and therefore it's not an identifier. – Lajos Arpad Jul 30 '23 at 15:04
  • Read about the spec regarding HTML4 https://www.w3.org/TR/html4/struct/global.html#adef-id. And HTML5 spec https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute. The relevant quote: "The id attribute specifies its element's unique identifier (ID)." – Lajos Arpad Jul 30 '23 at 15:06
  • I think you missed my last sentence -> `Of course duplicate ID's for anchor tag navigating, (what it was designed for), would make no sense at all...` But as your likely aware ID's have been abused over the years, and hardly used for anchor tag navigating. My point was your example `let's test your theory` is of course not testing anything. – Keith Jul 30 '23 at 15:06
  • @Keith I did not miss it, it just was not a good point to react to. I do not know why the id attribute was designed for originally, but I have been using the id attribute very effectively over the years and no, I did not limit its use to anchor navigation. It's a good way to create unique contexts. A more important point to address was that you claimed that id duplication is valid in HTML and it works. This is a factually wrong statement. It works, but it's invalid both according to HTML4 and HTML5 specs. – Lajos Arpad Jul 30 '23 at 15:16
  • One can cross the road when the semaphore is red, but the fact that you *can* does not mean that you *should*. – Lajos Arpad Jul 30 '23 at 15:16
  • I think you seemed to have taken my comment rather badly. I totally agree HTML spec wise duplicate ID's are invalid, and make total sense from a HTML only reason because from a HTML perspective there designed for anchor tags, and not Javascript. But from a Javascript perspective that the OP is using, the duplicate ID's part will work, my wording valid is probably the wrong word to use here, working would have been better. – Keith Jul 30 '23 at 15:40
  • `does not mean that you should` I don't think you should either, but ironically you will be surprised how many do :) eg. Try this on some popular sites -> `var ids=[...document.querySelectorAll('[id]')].map(m=>m.id); console.log(new Set(ids).size, ids.length);` A couple of examples -> `uTube = 698 3080`, `bbc news = 107 167` Even MDN -> `31 36` – Keith Jul 30 '23 at 16:00
  • @Keith I did not take your point badly. I just await a source that confirms your claim according to which ids were meant for anchor navigation only. "my wording valid is probably the wrong word to use here, working would have been better." I'm not debating you about its working, as we can check and reproduce searches where ids are used in selectors and they operate as one would expect them. You can quote examples where these principles are violated and you are right in quoting them. But this is why conventions and reviews as well as validators exist for. – Lajos Arpad Jul 30 '23 at 16:48
  • `ids were meant for anchor navigation only.` I never made that claim. https://www.w3.org/TR/1998/REC-html40-19980424/struct/global.html#adef-id In that link they explain uses for the `id` attribute, and out of all of them the only one I believe is still useful is -> `As a target anchor for hypertext links.`, Of course your free to use `id`s for scripting / styling and such,but ->. `var d = document.createElement('div'); d.id = 'useless_global'; document.body.appendChild(d); console.log(window.useless_global);` <-- does that feel right to you?. – Keith Jul 30 '23 at 19:04
  • @Keith "Of course duplicate ID's for anchor tag navigating, (what it was designed for), would make no sense at all..." – Lajos Arpad Jul 31 '23 at 08:09
  • Still didn't claim only. – Keith Jul 31 '23 at 08:28
  • @Keith then I'm not sure what we were debating about. – Lajos Arpad Jul 31 '23 at 08:36
  • Yeah, sorry. I think things here went slightly of tangent. My main point and first comment was just to let you know that your snippet didn't prove that multiple ID's are an issue, it would be like saying `document.querySelector('div')` means we can only have 1 div. IOW: you was using a singleton method to claim something was a singleton. Personally I think the spec needs updating here to save any confusion, multiple ID's are used and work, and enforcing this unique constraint could potentially break the internet. – Keith Jul 31 '23 at 09:49
  • 1
    @Keith now I see your point. The reason as of why I used `getElementById` in my answer was that this was the specific function call the asker was using in the question. I did not claim that duplicated ids cannot be found. I have proven that it will not be the case with `getElementById`, showing that the assumption in the question was wrong. Consequently, I explained that id duplication is invalid in HTML and one needs to avoid it. I'm aware of selectors being able to find duplicated ids, but I did not append such ideas into the answer to avoid promoting bad practices. – Lajos Arpad Jul 31 '23 at 10:28
  • @Keith so, instead I suggested the use of a class for non-unique items. – Lajos Arpad Jul 31 '23 at 10:29
  • 1
    This has been a really interesting discussion, and what I really like about it, that it's not got heated or personal, and that can happen on SO, debate is nice when done like this. I think 95% of what we are saying is in totally agreement anyway. :) – Keith Jul 31 '23 at 11:19
  • 1
    @Keith indeed. Excuse me for misunderstanding your point initially. I was arguing against a position you did not actually have due to this misunderstanding and that's why you thought I did not receive it well. Actually we agree on everything except about desirable habits regarding ids. But it would be boring to agree about everything, wouldn't it? – Lajos Arpad Jul 31 '23 at 11:35