0

Let say there's 3 times the same ID, I want to delete all of them except one. Example :

<div id = "parent_id">
     <div id = "id_1">
        <div id = "id_1-1"> </div>
        <div id = "id_1-1"> </div> // I want to delete this
        <div id = "id_1-1"> </div> // I want to delete this
        <div id = "id_1-2"> </div>
        <div id = "id_1-2"> </div> // I want to delete this
        <div id = "id_1-2"> </div> // I want to delete this
     </div>
     <div id = "id_2">
        <div id = "id_2-1"> </div>
        <div id = "id_2-1"> </div> // I want to delete this
        <div id = "id_2-1"> </div> // I want to delete this
        <div id = "id_2-2"> </div>
        <div id = "id_2-2"> </div> // I want to delete this
        <div id = "id_2-2"> </div> // I want to delete this
     </div>
     <div id = "id_3">
        <div id = "id_3-1"> </div>
        <div id = "id_3-1"> </div> // I want to delete this
        <div id = "id_3-1"> </div> // I want to delete this
        <div id = "id_3-2"> </div>
        <div id = "id_3-2"> </div> // I want to delete this
        <div id = "id_3-2"> </div> // I want to delete this
     </div>
</div>

Can it be done with a for loop ? Thanks in advance !

Bambou
  • 1,005
  • 10
  • 24
  • 1
    Wrong markup period! – Ele Mar 08 '18 at 22:14
  • 8
    This shouldn't happen in the first place. Element IDs should be **unique**. – PM 77-1 Mar 08 '18 at 22:15
  • 2
    Id supposed to be unique. Your html markup is wrong. – Mike Ezzati Mar 08 '18 at 22:16
  • It is probably feasible with certain browsers. However, as others have pointed out here, it is illegal to have more than one element with the same id, so the browser's behaviour would not be standardised, and the code might break any time. – Renardo Mar 08 '18 at 22:25
  • note: `document.querySelectorAll('#id_1-1')` (and the jQueery equivalent) **will** return all those elements - but it's still **bad practice** and technically *invalid markup* – Jaromanda X Mar 08 '18 at 22:35
  • https://jsfiddle.net/0cx4w4y4/1/ And the querySelectorAll appears to get them all, but jQuery will not. – Taplar Mar 08 '18 at 22:45
  • OK, @Taplar - I'll remove the comments, as they aren't helpful :p – Jaromanda X Mar 08 '18 at 22:48
  • @Taplar - that's interesting that jQuery doesn't catch them all! I could've sworn it used to!!! Good thing I deleted my comments :p – Jaromanda X Mar 08 '18 at 22:50
  • You can make jQuery do it with an attribute selector, but you take whatever performance hit there is between an id lookup and an attribute lookup, but you are making it work around the web standard at that point. – Taplar Mar 08 '18 at 22:52
  • Welcome to Stack Overflow! Please read [Why is “Can someone help me?” not an actual question?](https://meta.stackoverflow.com/q/284236) – NightOwl888 Mar 09 '18 at 13:52

6 Answers6

1

Assuming the duplicates follow the original, the following code does it

$('#parent_id').children('div').each(function(i, div) {
    var $first = $(div).children('div').first();
  var $next = $first.next('div');
  while($next.length > 0){
    if ($next.attr('id') === $first.attr('id'))
        $next.remove();
    else $first = $next;
    $next = $first.next('div');
  }
});

I created a fiddle.

But as everybody else mentioned, you have broken html, if you can change that id to say data-position, you'd fix that issue.

Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
1

I did that for the unexpected on jquery, your id's are correctly because are uniques but it's ugly for who makes css for this file anyways i think it's called BEM...

That's my example:

$('#parent_id').children('div').each(function(i){
      let removed = $('#id_' + (++i)).children('div').each(function(){
        $(this).remove();
      });
      //Think the algorithm..
      $(this).append($(removed[0]).html());
      $(this).append($(removed[3]).html());
    });

https://jsfiddle.net/SirXploSiv/vtrL9p54/27/

1

You could select all the elements based on the common id,

var list = jQuery('[id^=id_]');

Then filter them further by if they match the more specific version, ie id_1-1, and are not the specific indexes you specify.

list = list.filter((idx,element)=>{
  //getElementIndex is a custom util function to get element's index
  let indexInParent = getElementIndex(element);
  //Check if the element has the specific id format, and is not an element
  //at the indexes to keep
  return element.id.match(/id_\d-\d/) && ![0,3].includes(indexInParent);
});

If needing a different criteria for what to remove or what not to remove you would just modify the filter() method logic to accommodate.

After that just remove them.

list.remove();

Note though you should not use the same id more than once. If these id's are containing some sort of information, that information should be stored in data-* attributes. And if all the removed element's have something in common it might be beneficial to label them with a common class or data-* attribute that way removal could be coded in less instructions.

jQuery('[id^=id_]').filter((idx,element)=>{
  let indexInParent = getElementIndex(element);
  return element.id.match(/id_\d-\d/) && ![0,3].includes(indexInParent);
}).remove();


function getElementIndex (element) {
  return Array.from(element.parentNode.children)
              .indexOf(element);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id = "parent_id">
     <div id = "id_1">
        <div id = "id_1-1">a </div>
        <div id = "id_1-1">b </div> 
        <div id = "id_1-1">c </div> 
        <div id = "id_1-2">d </div>
        <div id = "id_1-2">e </div> 
        <div id = "id_1-2">f </div> 
     </div>
     <div id = "id_2">
        <div id = "id_2-1">g </div>
        <div id = "id_2-1">h </div> 
        <div id = "id_2-1">i </div> 
        <div id = "id_2-2">j </div>
        <div id = "id_2-2">k </div> 
        <div id = "id_2-2">l </div> 
     </div>
     <div id = "id_3">
        <div id = "id_3-1">m </div>
        <div id = "id_3-1">n </div> 
        <div id = "id_3-1">o </div> 
        <div id = "id_3-2">p </div>
        <div id = "id_3-2">q </div> 
        <div id = "id_3-2">r </div> 
     </div>
</div>
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
0

Uh oh

You should never have elements with the same ID. You should never EVER have elements with the same ID. Browsers do wonky shit when you have elements with the same ID (which you should never do).

There is no practical answer to your question because if you have elements with the same ID, everything will be horrendously broken. Attempting to manipulate the DOM when there are elements with the same ID will only lead to frustration and crushed dreams. If you have reached a situation where you have elements with the same ID, you have already lost.

More helpful answer: You might be able to do it, but there are no guarantees. At this point, any DOM manipulation is most likely undefined behavior. On firefox, I had success building a list of ids and removing any duplicates like so:

var elements = document.querySelectorAll("*[id]");
var usedIds = {};

for(let i = 0; i < elements.length; i++) {
    const id = elements[i].getAttribute("id");
    if(usedIds[id]) {
        elements[i].parentNode.removeChild(elements[i]);
    } else {
        usedIds[id] = true;
    }
}
EKW
  • 2,059
  • 14
  • 24
  • *everything will be horrendously broken* - not, perhaps your VCR will be reprogrammed, maybe your dog will run away, but the page will render :p – Jaromanda X Mar 08 '18 at 22:37
0

The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document).

The id attribute is most used to point to a style in a style sheet, and by JavaScript (via the HTML DOM) to manipulate the element with the specific id.

<element id="id">

You could use different attributes like class="yourname" or even your own attributes mycoolattribute="my little brother" to target multiple elements but keep in mind do not use multiple IDS! :)


Edit: You could use the query selector (jQuery) to catch the attribute called "ID" but I would really prefer to avoid this practice:

document.querySelectorAll('#myid')

I'm sure it is a good idea to have a close look at the docs!

-1

Use the :not and :first pseudo classes of css like this

$("parent_id").children("div").find("div:not(:first)")).remove();
Osama
  • 2,912
  • 1
  • 12
  • 15