简体   繁体   中英

How do I return or make null all other EventListeners if another is triggered using vanilla Javascript

What I am trying to accomplish is a code that when one of the buttons is clicked, the button gains the styles listed below and all other button styles return to null.

I assume it involves a boolean statement, but perhaps I am wrong.

You'll see below that I am attempting to use my "else if" statement to establish that when the event target does not equal "button", to return everything to null. However, that is clearly not working.

I have also tried ".==" and that didn't work.

Obviously, this can be done by creating an Eventlistener unique to each button, but I wanted to figure out how to do this dynamically.

CSS:

button {
  font-family: "sans-serif";
  margin: 1%;
  padding: 1%;
  cursor: pointer;
  font-size: 22px;
}

Here is my html:

<section id="button-container">
  <button>a</button>
  <button>b</button>
  <button>c</button>
  <button>d</button>
  <button>e</button>
</section>

Here is my Javascript:

var buttons = document.querySelectorAll('#button-container button');

buttons.forEach(button => {
  button.addEventListener("click", function(e) {
    if (e.target === button) {
      e.target.style.backgroundColor = "blue";
      e.target.style.color = "orange";
    } else if (e.target != button) {
      e.target.style.backgroundColor = null;
      e.target.style.color = null;
    }
  })
})

You have one listener per button, and so when the event occurs you are only accessing properties of that single button on which the event happened. Yet you would need to change also something that relates to the previously marked button.

I would put the listener on the container element, so you need to create only one listener, and don't need to copy it to make it apply to each button separately.

Secondly, you could also use a kind of anchor element which you move always before the button that should be "special", and then leave it to some smart CSS to do the rest.

It is any way better practice to use CSS classes instead of specific style property assignments in your JS code.

 var container = document.querySelector('#button-container'); var marker = document.querySelector('.marker'); container.addEventListener("click", function(e) { if (e.target.tagName === 'BUTTON') container.insertBefore(marker, e.target); });
 button { font-family: "sans-serif"; margin: 1%; padding: 1%; cursor: pointer; font-size: 22px; }.marker+button { background-color: blue; color: orange; }
 <section id="button-container"> <button>a</button> <button>b</button> <button>c</button> <button>d</button> <button>e</button> <span class="marker" /> </section>

Instead of modifying the style directly I would use a class instead:

button.active {
  background-color: blue;
  color: orange
}

When you click a button then add the active class to it:

button.addEventListener("click", function(e) {
  this.classList.add("active");
});

We now only have to add some logic to remove the active class from the previously clicked button.

We could either go over all the buttons and remove the class from all of them:

buttons.forEach(button => button.classList.remove("active"));

Or we query the DOM for the currently "active" button and remove it from that button only:

const activeButton = document.querySelector("#button-container button.active");
activeButton.classList.remove("active");

or we use the parentNode from the current button to "search":

const activeButton = button.parentNode.querySelector("button.active");

Or we use the "magic" of .getElementsByClassName() which returns a live collection (it will automatically update with the current set of elements with the given class) of all elements with a given CSS class:

const buttons = document.querySelector('#button-container');
const activeButtons = document.querySelector("#button-container").getElementsByClassName("active");

/* ... */

button.addEventListener("click", function(ev) {
  if (activeButtons.length) {
    activeButtons[0].classList.remove("active");  // there should always be only _one_ active button
  }

  this.classList.add("active");
});

Example:

 var buttons = document.querySelectorAll('#button-container button'); buttons.forEach(button => { button.addEventListener("click", function(e) { const activeButton = button.parentNode.querySelector("button.active"); if (activeButton) { activeButton.classList.remove("active"); } this.classList.add("active"); }) })
 button { font-family: "sans-serif"; margin: 1%; padding: 1%; cursor: pointer; font-size: 22px; } button.active { background-color: blue; color: orange; }
 <section id="button-container"> <button>a</button> <button>b</button> <button>c</button> <button>d</button> <button>e</button> </section>

The easiest way is to remember which one is the current one in a variable...

let current = null;
buttons.forEach(button => {
    button.addEventListener("click", e => {
        if (current) {
            current.style.backgroundColor = "";
            current.style.color = "";
        }
        current = button;
        current.style.backgroundColor = "blue";
        current.style.color = "blue";
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM