Viktor Grafskiy
Viktor Grafskiy

Reputation: 31

`transitionend` stops firing after several events

I have a tricky problem. When a user presses on a div I want to add a css class to that div with name .active, using css transition. Then, after a short timeout, I want to handle transitionend event where I will remove the class .active from the div. The problem is, if a user presses on the button too fast, say 15-20 times per second, transitionend eventually stops firing.

You can see this effect here(clickable link), open Chrome browser(I wasn't able to reproduce it in FF) and start clicking on the button as fast as you can. After 15-20 clicks transitionend will stop triggering.

I think, when transitionend handler is still working, a user can press the button once again and the div will get .active class, but it will not trigger transition event. The question is - is it possible to write bullet-proof code to clear the .active class using transitionend event only ?

Thank you.

*edit* embedded snippet below

var blk = document.querySelector('.animated-element');
var btn = document.querySelector('.button');
var ctr = document.querySelector('.click-counter');
var lgr = document.querySelector('.logger');

btn.addEventListener('click', function() {
  var currentValue = Number(ctr.innerHTML);
  ctr.innerHTML = ++currentValue;
  if (!blk.classList.contains('active')) {
  	blk.classList.add('active');
  }
});

blk.addEventListener('transitionend', function() {
  blk.classList.remove('active');
  var li = document.createElement('li');
  li.innerHTML = 'Transition end';
  lgr.appendChild(li);
});
.scene {
  position: relative;
  width: 300px;
  height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.animated-element {
  width: 200px;
  height: 200px;
  margin-bottom: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 2em;
  background-color: #ff0000;
  color: white;
  border-radius: 5px;
  transition: all 500ms;
}

.animated-element.active {
  font-weight: 700;
  /* background-color: #ff0055; */
}

.button {
  padding: 5px 10px;
  border: 2px solid black;
  border-radius: 5px;
  text-align: center;
  cursor: pointer;
  user-select: none;
}

.click-counter {
  position: absolute;
  top: 0;
  left: 0;
  min-height: 17px;
  min-width: 17px;
  padding: 2px 4px;
  color: gray;
  font-weight: bold;
  text-align: center;
  border: 2px solid gray;
  border-radius: 50%;
  user-select: none;
}

.logger {
  width: 300px;
  padding: 0;
  list-style: none;
  text-align: center;
}
<body>
  <main>
    <div class="scene">
      <div class="click-counter">0</div>
      <div class="animated-element">
        <span>ABC</span>
      </div>
      <div class="button">
        Press me several times
      </div>
    </div>
    <ul class="logger"></ul>
  </main>
</body>

Upvotes: 2

Views: 200

Answers (0)

Related Questions