I need to have a bound event listener function to reference itself, but I don't see a way to access itself in strict mode (arguments.callee is not available).
See the following code snippet for an example:
function callback(boundParam, event) {
// This does not work here as not 'callback' was added
// to the event bus but 'boundCallback'
eventBus.removeListener(callback);
}
function foo () {
const boundCallback = callback.bind({}, 7);
eventButs.addListener(boundCallback);
}
What are my options?
This is NOT a duplicate of JavaScript: remove event listener as I need to reference a bound function!
Maybe inline the handler so that you dont need to bind:
function foo () {
function callback (){
//...
eventBus.removeListener(callback);
}
eventBus.addListener(callback);
}
You could create a function that returns a reference to the bound function when called. Let's call that function getBoundCallback. Then, append it to the argument list of the bind() call in order to receive the function in callback. You should then be able to call getBoundCallback and get back the actual bound function:
function callback(boundParam, getBoundCallback, event) {
eventBus.removeListener(getBoundCallback());
}
function foo() {
let boundCallback;
const getBoundCallback = () => boundCallback;
boundCallback = callback.bind({}, 7, getBoundCallback);
eventButs.addListener(boundCallback);
}
Note how the declaration and initialisation of boundCallback are separated because of the reference to getBoundCallback being required for the statement initialising boundCallback.
Related
I want to dynamically return different values based on the event that changes the value of var inside the constructor function. When constructor function is created I get the return of the default value which is equal to doA, when I invoke it the first time, I get a call to someFunction from doA. When the event happens, I can see that event variable updates it is reference to refer to doB function, however, when I invoke someFunction a second time, I still get a call to doA instead of doB. Any suggestion of can I achieve what I intent?
Thank you in advance
PS - the code bellow is not a working code, it just a representation of what I am trying to achieve
function doA(){
function someFunction(){};
function someFunctionB(){};
}
function doB(){
function someFunction(){};
function someFunctionB(){};
}
function Main(){
var event;
addEventListener('change', (event) => {
if(someCondition){
event = doA();
}
if(otherCondtion){
event = doB();
}
});
function someOtherFunction(){
}
return{
...event,
someOtherFunction
}
}
const main = new Main();
main.someFunction(); //calling someFunction from doA
//event changes here
main.someFunction() //intent to call someFuntion doB but still calling someFunction from doA
'''
When I bind a function with the parent this passed in thisArg, I can't unbind the same named function expression, but without it I can unbind the function itself. Why is that?
This works:
choicesList.addEventListener("click", function() {
const self= this;
document.addEventListener("click", function checkClick(e) {
if (!e) e = event;
if (!self.contains(e.target)) {
document.removeEventListener("click", checkClick);
}
}, false);
});
This doesn't:
choicesList.addEventListener("click", function() {
document.addEventListener("click", function checkClick(e) {
if (!e) e = event;
if (!this.contains(e.target)) {
document.removeEventListener("click", checkClick);
}
}.bind(this), false);
});
The reason for this is issue is that calling bind() on a function returns a new instance of that function:
function someHandler() {
alert('hi');
}
const someHandlerBinded = someHandler.bind(document);
// Returns false, seeing as these are different instances of the function
console.log( someHandlerBinded === someHandler );
By setting an event handler directly, via the result of bind() as you are in your second block of code, this causes a new instance of that function handler to be passed to addEventListener(). This in turn means that the subsequent attempt to removing this handler on line:
document.removeEventListener("click", checkClick);
will fail, seeing that the the defined function checkClick is not the same as the actual handler function used for that click event (ie the new function instance returned from function checkClick(){ ... }.bind())
One way to resolve this might be the following:
choicesList.addEventListener("click", function() {
// Declare the bound version of the click handler
const boundClickHandler = function checkClick(e) {
if (!e) e = event;
if (!this.contains(e.target)) {
// Removing the result of bind, rather than the declared
// checkClick handler
document.removeEventListener("click", boundClickHandler);
}
}.bind(this)
// Adding the result of bind as you currently are doing
document.addEventListener("click", boundClickHandler, false);
});
It's because this is in a function that is nested within another function and the nested function doesn't have the same invocation context as the outer one. The first one works because you are caching the object that the outermost this is referencing and you are then able to correctly reference it in the inner function.
You can read more about the volatility of this here.
i want to add an EventListener to a button via the .addEventListener Method.
Here is the code:
myElement[i].addEventListener('click', buttonLink);
This works fine and it passes the event as a value to the method. Here is the method-head:
function buttonLink(e) {
//Now i can access the srcElement via:
e.srcElement.id ...
}
The problem is, if i pass parameters to the method it hides the e parameter and it is completely invisible inside the method. Is there a way to pass my own values AND(!) the event to the eventListener?
Thanks in advance
Pass an anonymous function to addEventListener and call the callback from within that:
myElement[i].addEventListener('click', function (e) {
buttonLink(e, somethingElse, anotherThing);
});
Below I have given 2 ways to pass the function arguments. Both works for addEventListener and removeListener:
Method 1: Wrapper Function:
let myElement = document.getElementById('myId');
function wrapperFunction(e) {
myFunction(e, 5, 9); //define your function and pass arguments(5,9)
}
myElement.addEventListener('event', wrapperFunction);
myElement.removeEventListener('event', wrapperFunction);
Note: 'e' event is comes for free from the 'addEventListener' function.
Method 2: Curring
var myFunction = function (arg1, arg2) {
return function curriedFunc(e) {
myFunction(e, arg1, arg2); // define your function and pass arguments(5,9)
};
};
let myElement = document.getElementById('myId');
let myRef = myFunction(5,9);
myElement.addEventListener('click', myRef);
myElement.removeEventListener('click', myRef);
From https://www.codegrepper.com/code-examples/javascript/can+I+have+multiple+arguments+in+addEventListener:
var someEventHander=function(event,param1,param2)
{
console.log(event,param1,param2);
}
//add listener
document.getElementById("someid").addEventListener('click',someEventHander.bind(event,'param1','param2'), false);
This doesn't appear to be usable for removeEventListener though.
I have the javascript code for a link click:
document.getElementById('giddy').onclick = function {
alert(this.href);
};
and I want to separate the function part of it...I have
document.getElementById('giddy').onclick = poro(this);
function poro(yyyy) {
alert(yyyy.href);
};
But it is not working (says undefined in the alert)...what am I doing wrong?
You don't need to pass this as a parameter. this will be the context for the function when it is called. You should just have:
document.getElementById('giddy').onclick = poro;
function poro() {
alert(this.href);
};
Get rid of (this) and use this in the function instead of yyyy.
document.getElementById('giddy').onclick = poro;
function poro() {
alert(this.href);
};
You're immediately calling the poro function.
Essentially, you're telling Javascript that the element's onclick value will equal the result of calling the poro(this [window] ) function.
To get around this, you can wrap the poro(this) function inside an empty function, like so:
document.getElementById('giddy').onclick = function(){poro(this)} function poro(yyyy) { alert(yyyy.href); };
You may also want to consider using an eventListener, as it allows room for expansion.
Almost there! You should do:
document.getElementById('giddy').onclick = function(){ poro(this); }
function poro(yyyy) {
alert(yyyy.href);
};
Note poro(this); wrapped in an anonymous function.
I'd recommend using addEventListener instead of the onclick method.
Try this:
var giddy = document.getElementById('giddy');
giddy.addEventListener('click', function(e) { poro(this); }, false);
function poro(yyyy) {
alert(yyyy.href);
}
since you are using jquery use :
$('#giddy').click(function(){ poro($(this));});
or you can use the bind() function
$("#giddy").bind("click", $(this), poro);
I have a function that listens for a click on the screen and fires a callback. It is part of a Helper object (which is why is preceded by the term Helper in my sample code. That is irrelevant however.
var Helper = {
bodyClickListener: function(fn) {
var window = document.getElementsByTagName('body')[0];
window.click();
CORE.dom.on(window, 'click', function(event) {
CORE.dom.off(window, 'click');
fn(event);
});
}
}
I need to be able to pass a function into this function with a parameter that has been previously set.
function someFunction() {
var popup = document.getElementById('tagResultsPopup');
Helper.bodyClickListener(function(popup) {
return function(event) {
event.stopPropagation();
removePopup(popup);
};
}(document.getElementById('tagResultsPopup')));
function removePopup(element) {
if(element) {
element.parentNode.removeChild(element);
}
};
}
The code above works, but you'll notice that I have to set the popup variable inside of the callback function. It has already been set above. How do I pass a reference to the earlier variable into the callback function.
If I understand your question correctly, you don't need to do much. You can just use the popup variable defined outside.
var popup = document.getElementById('tagResultsPopup');
Helper.bodyClickListener(function(event) {
event.stopPropagation();
//Don't set it
//var popup = document.getElementById('tagResultsPopup');
removePopup(popup);//popup will refer to the correct variable
});
The function that you are passing to bodyClickListener is a closure. You can simply reference 'popup' inside that function without any problem. You don't have to create a new variable.
The answer was to use closure in this way:
Helper.bodyClickListener(function(popup) {
return function(event) {
event.stopPropagation();
removePopup(popup);
};
}(document.getElementById('tagResultsPopup')));
That way the callback function has access to the variable I pass into the parameter function. So here, the return is actually the function I am passing as the callback.