Javascript removeEventListener not working
This is because that two anonymous functions are completely different functions. Your removeEventListener
's argument is not a reference to the function object that was previously attached.
function foo(event) {
app.addSpot(event.clientX,event.clientY);
app.addFlag = 1;
}
area.addEventListener('click',foo,true);
area.removeEventListener('click',foo,true);
why removeEventListener is not working
JavaScript is very particular when it comes to removing event listeners. You can only remove the same event listener that you have previously added. It also needs to match whether it’s bubbling.
Among other things, that means that you cannot remove an anonymous event listener since you have no way of identifying it.
In your case, you’re compounding the problem by actually attempting to remove a newly created event listener.
The only way to remove an event listener is to ensure that it has a name. In your case, it would be as follows:
var random=myFunction("random: ");
document.getElementById("demo").addEventListener("click", random,false);
function myFunction(t) {
var x = function(){
document.getElementById("demo").innerHTML = t+Math.random();
};
return x;
}
function removeHandler() {
document.getElementById("demo").removeEventListener("click", random,false);
}
Note:
- There is a variable name (
random
in this case) to identify the event listener function - I have also added
false
as a third parameter to ensure that the remove matches the add.
Javascript removeEventListener not doing anything with anonymous function, no easy way to do this?
.removeEventListener()
takes the same callback function as a second argument that was used to add the event listener, i.e. that was passed as a second argument to .addEventListener()
method.
In your case, you are using anonymous function, so the one you pass to .addEventListener()
method is different from the callback function that you have passed to .removeEventListener()
method. Hence, registered event listeners are not removed.
Since you mentioned in your question that you used anonymous functions because you need to pass an argument to the event handler function. You can create a function that you want to use as a event handler, then use Function.prototype.bind()
to get another function, save a reference to this function returned by Function.prototype.bind()
somewhere and then use this new function as a event handler.
Later, when you need to remove the event listeners, you can remove them easily because references of the event handler functions were already saved.
Following code snippet shows an example:
const btn = document.querySelector('#one');
const removeBtn = document.querySelector('#two');
function handleClick(val) {
console.log(val);
}
// 123 is the argument that we want to pass to the event handler
const bindFunc = handleClick.bind(null, 123);
btn.addEventListener('click', bindFunc);
removeBtn.addEventListener('click', () => {
btn.removeEventListener('click', bindFunc)
});
<button id="one">Click</button>
<button id="two">Remove Click Listener</button>
Javascript removeEventListener not working - event listener remains
When calling removeEventListener, you have to give it the same function instance than to addEventListener:
var lb = document.body;
var callback = function(event){
keyPress(event.keyCode)
};
if(lb.addEventListener){
lb.addEventListener('keyup', callback, false);
}
//In another function.
if(document.body.removeEventListener){
document.body.removeEventListener('keyup', callback, false);
}
jQuery makes it easier to deal with this, thanks to its namespaced events feature:
$(lb).on('keyup.my_namespace', function () { ... })
// later
$(lb).off('keyup.my_namespace');
Javascript's removeEventListener not working
bind
creates a new function with a new reference. this.ticTacToeControl
and this.ticTacToeControl.bind(this)
are two different functions with two different references. Store the function reference in a variable and use it to remove the event listener.
class Controller {
constructor() {
navigationView.addHoverEventHandlers(navigationView.hoverFunction);
navigationView.addClickHandler(this.showContent.bind(this));
}
showContent() {
ticTacToeView.renderContent(navigationView.clickedContent);
this.handler = this.ticTacToeControl.bind(this);
ticTacToeView.addClickEventHandler(this.handler);
ticTacToeView.addHoverHandler(ticTacToeView.hoverFunction);
}
ticTacToeControl(clickedBox) {
if (ticTacToeView.checkIfBoxEmpty(clickedBox)) {
ticTacToeView.createMark(clickedBox, ticTacModule.activePlayer);
ticTacModule.updateBoardState(clickedBox);
ticTacModule.changeActivePlayer();
ticTacToeView.highlightActivePlayer(ticTacModule.activePlayer);
ticTacModule.checkForWinner();
if (ticTacModule.winner) {
ticTacToeView.renderWinner(ticTacModule.winner);
ticTacToeView.removeClickEventHandler(this.handler);
}
}
}
}
removeEventListener not working as i expect
The listener that is set is not increase
, it's basically an anonymous function () => increase(event)
to which you don't have a reference.
Since you are setting it as onclick
attribute, all you need to do is div.onclick = null
.
However, it would be better to not use onclick
in the first place since it relies on the functions existing in the global scope, prevents proper separation of code and markup and also prevents securing your page with CSP (content security policy).
If you were to adjust the event listener instead in app.js
like this...:
document.getElementById('my-div').addEventListener('click', increase)
...then your existing code to remove the listener would work.
JavaScript: remove event listener not working
debounce(showPopup)
isn't same as just debounce
.
debounce(showPopup)
call executes code when debounce
just reference to the function.
To be able to removeEventListener
you need pass same function reference which you pass to the addEventListener
.
Assign debounce(showPopup)
to some variable and use it for event subscription/unsubscription.
Example:
const elementToListenForScroll = document.querySelector('.howitworks__mainheading'); const distanceToTop = elementToListenForScroll.getBoundingClientRect().top;
var realReference = debounce(showPopup); function debounce(func, wait = 20, immediate = true) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; } function showPopup() { const currentScrollPosition = window.scrollY; if(currentScrollPosition > distanceToTop) { console.log('hey it works'); window.removeEventListener('scroll', realReference); } } window.addEventListener('scroll', realReference);
removeEventListener not working as expected
The problem is that on every click
, you're creating a new clickOutside
function; if you use that function with removeEventListener
, since there's no event registration with that exact function object, nothing is removed.
Instead, remember the handler object so you can use it for removal, see notes:
new Vue({ el: "#app", data: { menuVisible: false, clickOutside: null }, methods: { click(e) { var clickSource = e.target; var app = document.getElementById("app"); var that = this; // Only create it if we don't already have it if (!this.clickOutside) { // Create it this.clickOutside = function clickOutside(e) { console.log("clickOutside triggered"); if (e.target != clickSource) { console.log("It's an outside click"); that.menuVisible = false; // Remove it app.removeEventListener("click", that.clickOutside); } }; }
if (this.menuVisible === false) { this.menuVisible = true; app.addEventListener("click", this.clickOutside); } else if (this.menuVisible === true) { this.menuVisible = false; app.removeEventListener("click", this.clickOutside); } } }});
body { margin: 0;}
#app { min-height: 100vh; background-color: #ddd;}
<script src="https://unpkg.com/vue"></script>
<div id="app"> {{menuVisible}} <button @click="click"> click </button></div>
removeEventListener not working?
You should pass exactly the same function to both addEventListener
and removeEventListener
.
MyConsole.prototype.onEnter = function(callback) {
const callCallback = function(e) {
e.preventDefault();
if (e.keyCode === 13 && typeof callback === "function") {
setTimeout(function () {
callback();
}.bind(this), 0);
this.textAreaInputDiv.removeEventListener("keyup", callCallbackBound, true);
}
};
const callCallbackBound = callCallback.bind(this);
this.textAreaInputDiv.addEventListener("keyup", callCallbackBound, true);
};
In fact an arrow function would be a better option here since it does not have its own this
.
And you probably meant callback.bind(this)
in the setTimeout
so I let myself to fix that as well:
MyConsole.prototype.onEnter = function(callback) {
const callCallback = (e) => {
e.preventDefault();
if (e.keyCode === 13 && typeof callback === "function") {
setTimeout(callback.bind(this), 0);
this.textAreaInputDiv.removeEventListener("keyup", callCallback, true);
}
};
this.textAreaInputDiv.addEventListener("keyup", callCallback, true);
};
Related Topics
How to Sort an Array of Objects with Jquery or JavaScript
How to Load Data from a CSV File in D3 V5
Date Constructor Returns Nan in Ie, But Works in Firefox and Chrome
How to Record Webcam and Audio Using Webrtc and a Server-Based Peer Connection
How to Get a HTML Element from a String with Jquery
How to Add and Remove Classes in JavaScript Without Jquery
How to Ensure a <Select> Form Field Is Submitted When It Is Disabled
Where Should I Put the CSS and JavaScript Code in an HTML Webpage
How to Generate the Opposite Color According to Current Color
Uploading Multiple Files to Google Drive with Google App Script
Why Does JavaScript Object Show Different Values in Console in Chrome, Firefox, Safari
Why Do Results Vary Based on Curly Brace Placement
How to Check If Geolocation Has Been Declined with JavaScript