Using AddEventListener And RemoveEventListener Twice On A Single Button In JavaScript
I am trying to create a stopwatch in a browser where the time is either captured upon 'capture' (allowing the timer to continue) or 'stop' (which will also stop the timer). To do so, I want a single html button to alternate between two labels and corresponding functions ('start' and 'stop and capture'). I have tried to use two instances of addEventListener, each with an associated removeEventListener. After reading this useful article, I wrote the following code:
var button = document.getElementById("start");
function onStart() {
start();
document.getElementById("capture").style.visibility = 'visible'; // show capture button
document.getElementById("start").innerHTML = "Stop & Capture";
button.addEventListener("click", function() {
onCapture(); // assigns value to a new variable
onStop();
button.removeEventListener("click", arguments.callee, false); // remove this EventListener
}, false);
}
function onStop() {
stop();
document.getElementById("capture").style.visibility = 'hidden'; // hide capture button
document.getElementById("start").innerHTML = "Start";
button.addEventListener("click", function() {
onStart();
button.removeEventListener("click", arguments.callee, false); // remove this EventListener
}, false);
}
However, the behaviour of the 'start' / 'stop and capture' button is unexpected and saves more and more time instances every time it is pressed. My guess was that the removeEventListener isn't working, but I might be wrong. The associsated html is:
<div>Time: <span id="time"></span></div>
<button onclick="onStart()" id="start" class="start" style="width:150px">Start</button>
<button onclick="onCapture()" id="capture" style="visibility:hidden">Capture</button>
<button onclick="reset()" id="reset">Reset</button>
Answer
So, after spending far too long trying various solutions, it turned out that the problem was using removeEventListener
with anonymous functions. Here is the code that worked properly:
function onStart() {
document.getElementById("start").removeEventListener("click", onStart, false); // remove listener
start();
document.getElementById("capture").style.visibility = 'visible'; // show capture button
document.getElementById("start").innerHTML = "Stop & Capture";
document.getElementById("start").addEventListener("click", onStop, false); // add listener
}
function onStop() {
document.getElementById("start").removeEventListener("click", onStop, false); // remove listener
onCapture();
stop();
document.getElementById("capture").style.visibility = 'hidden'; // hide capture button
document.getElementById("start").innerHTML = "Start";
document.getElementById("start").addEventListener("click", onStart, false); // add listener
}
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM