skip to Main Content

I need to remove all buttons except the one which was clicked (perhaps using e.target.id?) – according to its index (using for loop.

I tried to create variable and declared it let buttonsX = buttons[i] so I could refer to it later in the if statement as !buttonsX and then it would call all the array buttons EXCEPT the button with the current index (triggered by a mousedown event).

But nothing happened.

I read there are the pull() & splice() functions but they would just require unnecessary lines of code that could’ve been prevented by a smaller code.

Other than them – I haven’t found any resources about such a function on the internet.

Also, it must be pure javascript,

Thank you very much.

3

Answers


  1. You can simply use .filter() and check for the elements being different from the one you are not interested in:

    let myArray = [...document.querySelectorAll(".container > button")];
    console.log(myArray);
    
    let filteredArray = myArray.filter(item => (item !== document.getElementById("btn-5")));
    
    for (let element of filteredArray) {
        element.style.backgroundColor = "green";
    }
    <div class="container">
        <button id="btn-1">1</button>
        <button id="btn-2">2</button>
        <button id="btn-3">3</button>
        <button id="btn-4">4</button>
        <button id="btn-5">5</button>
        <button id="btn-6">6</button>
        <button id="btn-7">7</button>
        <button id="btn-8">8</button>
        <button id="btn-9">9</button>
        <button id="btn-10">10</button>
        <button id="btn-11">11</button>
    </div>
    Login or Signup to reply.
  2. To complete this task in pure JS, you can use the forEach method to loop through all buttons and remove the ones that are not the clicked one. You can use the e.target to get the button that was clicked and then compare it to each button in the loop.

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Remove Buttons Example</title>
    </head>
    <body>
    <button id="btn1">Button 1</button>
    <button id="btn2">Button 2</button>
    <button id="btn3">Button 3</button>
    <button id="btn4">Button 4</button>
    
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const buttons = document.querySelectorAll('button');
    
            buttons.forEach((button, index) => {
                button.addEventListener('mousedown', (e) => {
                    buttons.forEach((btn, i) => {
                        if (i !== index) {
                            btn.remove();
                        }
                    });
                });
            });
        });
    </script>
    </body>
    </html>
    

    Hope this will help.

    Login or Signup to reply.
  3. One way to achieve the desired behaviour would be to register an event handler on an element wrapping the buttons. When the event is triggered, check if a button is clicked. If the user didn’t click a button, exit early. If the user did click a button, loop through all the buttons within the container and remove them, except if the button matches the clicked button.

    for (const buttonContainer of document.querySelectorAll(".button-container")) {
      buttonContainer.addEventListener("click", function (event) {
        const path = getPath(this, event.target);
        const clickedButton = path.find(elm => elm.matches(".button-container .removable-button"));
        
        if (!clickedButton) return;
        
        for (const removableButton of this.querySelectorAll(".removable-button")) {
          if (removableButton === clickedButton) continue;
          removableButton.remove();
        }
      });
    }
    
    /**
     * Returns an array containing the element path
     * to get from ancestor to target. Both ancestor
     * and target are included within the array.
     * If target is not present within ancestor
     * undefined is returned instead.
     */
    function getPath(ancestor, target) {
      if (!ancestor || !target) return;
      const currentPath = [];
      
      while (target) {
        currentPath.push(target);
        if (target === ancestor) {
          currentPath.reverse();
          return currentPath;
        }
        target = target.parentElement;
      }
    }
    <div class="button-container">
      <button class="removable-button">A</button>
      <button class="removable-button">B</button>
      <button class="removable-button">C</button>
    </div>
    
    <div class="button-container">
      <button class="removable-button">D</button>
      <button class="removable-button">E</button>
      <button class="removable-button">F</button>
    </div>
    const path = getPath(this, event.target);
    const clickedButton = path.find(elm => elm.matches(".button-container .removable-button"));
    

    The above is optional in the current snippet and could be replaced by:

    const clickedButton = event.target;
    

    However if you plan to nest other elements within the button, like <img>, <span>. The simplified version no longer works, since event.target is set to the deepest element clicked. So if I click "text" in <button><span>text</span></button> then event.target will be the <span> element, not the button.

    Note that this in the event handler is the element that the event is attached to. In this case the button container <div>, it’s the same as event.currentTarget.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search