Reputation: 77
I have a function in my addEventListener (#btn-1) that I want to remove eventually. I know that saving the function to a variable is the way to do it, but passing the "this" won't work unless it's wrapped in a function, which in turn won't be able to be removed now because it's either an anonymous function or it's not a reference to the same function even if it's named. Is there any way to do this?
const anonFunction = function(dis, str) {
console.log(dis);
console.log(str);
}
const myFn = function() {
anonFunction(this, 'hello world');
}
document.querySelector('#btn-1').addEventListener('click', function() {
anonFunction(this, 'hello world');
});
document.querySelector('#btn-2').addEventListener('click', function() {
// doesn't work
document.querySelector('#btn-1').removeEventListener('click', anonFunction);
});
<button id="btn-1" type="button">Call Function</button>
<button id="btn-2" type="button">Remove Event Listener</button>
UPDATE: SOLVED
Making another function calling the main function assigned to a variable and having that as the function to insert on adding and removing event listeners worked.
const anonFunction = function(dis, str) {
console.log(dis);
console.log(str);
}
const myFn = function() {
anonFunction(this, 'hello world');
}
document.querySelector('#btn-1').addEventListener('click', myFn);
document.querySelector('#btn-2').addEventListener('click', function() {
document.querySelector('#btn-1').removeEventListener('click', myFn);
});
<button id="btn-1" type="button">Call Function</button>
<button id="btn-2" type="button">Remove Event Listener</button>
Upvotes: 2
Views: 470
Reputation: 43870
If you name your functions and be mindful of scope you can:
removeEventListener()
By passing the Event Object:
echo(' From A ', e)
/* Event Object ⬆️ is passed by default by all event handlers.
Commonly used variables are e, evt, and event */
We can use the .target
property which always references the origin of event, or in layman's terms, the tag that the user interacted with. (ex. the <button>
the user clicked, the <input>
the user typed data into, the <area>
the user mouseovered, etc.)
let msg = `This data was transferred from ${e.target.tagName}.${e.target.className}`
/* Reference to e.target passed from one event handler to another
still maintains the same reference */
while e.target
is reliable, there are some events that do not reference event origin in a useful way like for instance the "submit" event. A "submit" when triggered will reference the <form>
as e.target
not the submit <button>
.
In this particular situation, this
will be lost and will be undefined
. At that point, we can call echo(string, e)
and reestablish what this
points to:
echo(text, e); // Delegated to .B
echo.call(this, ' From A ', e); // Delegated to .A
In the example when .B
is clicked this
is undefined
and when .A
is clicked, this
points to .A
even though both .A
and .B
were bound to the same event handlers.
document.querySelector('.A').addEventListener('click', named);
document.querySelector('.B').addEventListener('click', named);
function named(e) {
if (this.matches('.B')) {
const text = this.textContent;
echo(text, e);
}
if (this.matches('.A')) {
echo.call(this, ' From A ', e);
}
}
function echo(string, e) {
let msg = `This data was transferred from ${e.target.tagName}.${e.target.className}
ECHO: ${string.repeat(12)}
Who is this? ${this.className}`;
document.querySelector('.X').value = msg;
}
document.querySelector('.C').addEventListener('click', unbind);
function unbind(e) {
document.querySelector('.A').removeEventListener('click', named);
}
<button class='A' type="button">A</button>
<button class='B' type="button">B</button>
<textarea class='X' rows='5' cols='50'></textarea>
<button class='C' type="button">C - Click to Unbind A & B</button>
Upvotes: 1
Reputation: 780724
Just name your function that uses this
.
const anonFunction = function(dis, str) {
console.log(dis);
console.log(str);
}
const listener = function() {
anonFunction(this, 'hello world');
};
document.querySelector('#btn-1').addEventListener('click', listener);
document.querySelector('#btn-2').addEventListener('click', function() {
// doesn't work
document.querySelector('#btn-1').removeEventListener('click', listener);
});
<button id="btn-1" type="button">Call Function</button>
<button id="btn-2" type="button">Remove Event Listener</button>
Upvotes: 3