I have a toggle whose checked status I am calling with jQuery. Every time I click the toggle from unchecked to checked, the console logs "do this!" twice. Why does this function fire twice and what is the workaround to get it to fire once?
$("#my-toggle").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function() {
if (document.getElementById('my-checkbox').checked) {
console.log("do this!")
}
});
.switch {
position: absolute;
top: 15%;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before,
.slider .number {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
.slider .number {
background: none;
font-size: 14px;
left: 9px;
top: 9px;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before,
input:checked+.slider .number {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<label class="switch">
<input type="checkbox" id="my-checkbox">
<span class="slider round" id="my-toggle"></span>
</label>
My final HTML looks like this, for which the event fires three times:
<label class="switch">
<input type="checkbox" id="my-checkbox">
<span class="slider round" id="my-toggle">
<span class="number">00</span>
</span>
</label>
There are two
transitionendevents firing: one from your#my-toggle<span>, one from your::beforepseudo element. You need to differentiate those two events. You’d need the event argumentefor that.The only difference is then found in
e.originalEvent.propertyName(for the corresponding CSS property) ande.originalEvent.pseudoElement.So let’s check for that last property in the
ifcondition.Also put another
&& e.target == thisin there, since thetransitionendevent is also firing for children because the event bubbles up. Since you’re only listening to the event on the parent<span>, you can’t simply calle.stopPropagationwhich would only be useful to prevent the parent(s) from firing the event.