This question already has answers here:
JQuery callback to previously defined function
(3 answers)
Closed 7 years ago.
I'm having issues with writing some of my first JQuery code. I'm experimenting with some Codecademy stuff, just messing around and seeing how it works. Right now I'm pretty confused about an issue with anonymous functions: calling a function anonymously works but naming the function and calling it by name does not. The code is supposed to, on clicking an icon, open a menu from the left side of the screen and shift the rest of the page to the right; then do the reverse on clicking the close icon. The first code block works perfectly, the second just opens and closes the menu immediately after the page loads and then does nothing. Is there something I'm missing about order of operations in JS/JQuery or what?
Anonymous:
function main() {
$('.icon-menu').click(function() {
$('.menu').animate({left:'0px'}, 200);
$('body').animate({left:'285px'}, 200);
});
$('.icon-close').click(function() {
$('.menu').animate({left:'-285px'}, 200);
$('body').animate({left:'0px'}, 200);
});
}
Named:
function main() {
$('.icon-menu').click(open());
$('.icon-close').click(close());
}
function open() {
$('.menu').animate({left:'0px'}, 200);
$('body').animate({left:'285px'}, 200);
}
function close() {
$('.menu').animate({left:'-285px'}, 200);
$('body').animate({left:'0px'}, 200);
}
Thanks to anybody who can enlighten me.
You have
$('.icon-menu').click(open());
() calls a function.
You are calling open immediately and then passing its return value (undefined) to click.
Remove the () and pass the function instead.
Remove the parentheses. open() and close() call the functions, but you just want to pass a reference to the function.
function main() {
$('.icon-menu').click(open);
$('.icon-close').click(close);
}
Remove the brackets after function within clickhandler, because you are executing them emediatly with this syntax.
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
I know this may seems silly but I'm a beginner and I just need to make sure that I understand it well:
In JavaScript when I define an event listener, the callback function is called without () to prevent immediate execution, like the below example:
document.querySelector('#button').addEventListener('click',eventHandler)
function eventHandler() {
alert('clicked')}
my confusion is if implemented the above in a class and defined the eventHandler callback function as a method, I have to use () when I call it, like the below example:
class home {
constructor(){
this.button = document.querySelector('#button')
this.clickEvent()
}
//events
clickEvent(){
//here i have to use eventHandler() not eventHandler
this.button.addEventListener('click',()=>this.eventHandler())
}
//method
eventHandler(){
alert('clicked')
}
}
new home()
In code snippet with class, you are passing a function to addEventListener function which then calls the eventHandler function.
() => this.eventHandler() is an arrow function which executes this.eventHandler() inside its body
if you remove the arrow function then you will have to pass the name of the function instead of calling it
this.button.addEventListener('click', this.eventHandler)
Edit:
keep in mind that if the eventHandler method uses this, then you may run into problems because of how value of this is set in different cases.
Currently, eventHandler function isn't using this but you should read how to access correct this inside callbacks.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 2 years ago.
Recently, I've come across this problem where I had two methods in a class. One was referring to another but the other wasn't being recognized even though I could execute them individually.
class ButtonProcessor {
buttonClick() {
this.otherMethod();
}
otherMethod() {
console.log("This does not work!");
}
}
var buttonProcessor = ButtonProcessor;
document.getElementById("button").onclick = buttonProcessor.buttonClick;
The first method was called from a button click which was associated with a callback to that method.
One solution I found for this is to make the method that is called by the button a seperate function from the class and make it reference a class object that was already being used else-where. This is because apparently, when a method is referenced in a callback, using this to refer to another method doesn't work, because the callback only considers that one method.
class ButtonProcessor {
otherMethod() {
console.log("This does work!");
}
}
var buttonProcessor = ButtonProcessor;
function buttonClick() {
buttonProcessor.otherMethod();
}
document.getElementById("button").onclick = buttonProcessor.buttonClick;
Could there be another way to fix this?
This question already has answers here:
Use arrow function in vue computed does not work
(6 answers)
Closed 5 years ago.
I am using a lambda expression within the methods section of a Vuejs component.
The example is below
I trigger alertyou() and get the alert, click okay. Then in the vue developer tools I see this.activated becomes true.
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
activated: false
}
},
methods: {
alertme: () => { alert('Clicked'); this.activated = false; },
alertyou() {
alert('Alert You');
this.activated = true
}
}
}
However, when I click the button that triggers the alertme lambda. I get the alert message, click okay. But then this.activated stays true!
What is going on here is this a limitation with lambdas? Can you only trigger one statement per lambda? Or does this have to deal with scope once an alert is fired?
What is going on here is this a limitation with lambdas? Can you only trigger one statement per lambda? Or does this have to deal with scope once an alert is fired?
It’s neither.
An arrow function keeps this bound to the context it was when the arrow function was created. In this case, this is not the vue instance. It’s probably window
A function declared on an object using the function keyword (or the ES6 object shorthand style) will normally have this bound to the object on which the function is declared.
That’s why you can access this.activated on alertyou but not alertme
You’ll want to use the same syntax as alertyouto declare the alertme method.
Change alertme: () => { alert('Clicked'); this.activated = false; } to alertme() { alert('Clicked'); this.activated = false; }. You can see a working example here
This question already has answers here:
addEventListener calls the function without me even asking it to
(5 answers)
Closed last month.
I've noticed a difference between function and function() for addEventListener's callback.
Which isn't a problem till I tried passing a parameter. Basically,
element.addEventListener("hover", logInput, false );
function logInput(){
console.log('registered!');
}
works as intended, but adding parenthesis will cause it log immediately, without continual response to the event trigger:
element.addEventListener("hover", logInput(), false );
function logInput(){
console.log('registered!');
}
Why is this? And how can I get it to work while passing a parameter such as:
element.addEventListener("hover", logOnInput(this), false );
function logOnInput(triggeredElement){
console.log(triggeredElement);
}
(If you really want the triggered element, don't pass anything. this will automatically be set to the triggered element.)
element.addEventListener("hover", logOnInput, false);
function logOnInput(){
console.log(this);
}
To answer your more general question...
There are a few ways to pass a function as an argument with certain arguments already set (this is referred to as "partial application"). If you are able to use modern JavaScript features, the simplest way is probably to use an arrow function.
element.addEventListener("hover", () => logOnInput(foo), false);
function logOnInput(message){
console.log(message);
}
This will only work on very modern browsers. It won't work, for example, in IE 11. In order to support older browsers, you can use the longer form of a function expression.
element.addEventListener("hover", function() {logOnInput(foo);}, false);
function logOnInput(message){
console.log(message);
}
Or you could define a separate function (won't work with this but will work with other variables).
element.addEventListener("hover", logFooOnInput, false);
function logOnInput(triggeredElement){
console.log(triggeredElement);
}
function logFooOnInput() {
logOnInput(foo);
}
Or you could use bind.
element.addEventListener("hover", logOnInput.bind(null, foo), false);
function logOnInput(message){
console.log(message);
}
Its a javascript when you want to call a function you use parentheses. Without parentheses outside a function is useless. But inside a function as argument you use the function without the parentheses so that when that event occurs then only it would run. If you call a function using parentheses inside function argument it will be executed immediately and would also run when the event occurs. To call a function with its parameters inside a function and just to invoke in that event you need to use the bind method like below:
element.addEventListener("hover", logOnInput.bind(null, argument1, argument2, etc), false );
However, if you want to select the context as this then I would recommend you to use like this:
function logOnInput(elem,arguments) {
//now you can use **elem** to refer **this**
}
And use the anonymous function for the hover event like this:
element.addEventListener("hover", function(){
logOnInput(this,arguments)
}, false );
The bind function is probably the cleanest option if you are targeting on modern browsers only. Some blogs talk about the loss of performance comparing bind with anonymous functions. Some blogs talk bad about anonymous functions.
On the anonymous function. All goes well passing arguments on the addEventListener. But when you get to removeEventListener passing the arguments won't work the same way as in the addEventListener.
I found this dude, in 2005, with the answer:
http://www.codingforums.com/dom-and-json-scripting/5909-how-pass-arguments-independently-using-addeventlistener.html
In resume, set your anonymous function to be equal to a newly declared "thing". Idk if this is a var or an expression. I tested var and it wont' work. Idk the technicalities of this at this point, but it works.
function addhoverIn(SELECTED) {
SELECTED.addEventListener("mouseover", addHIn = function() { hoverIn(SELECTED); }, false);
}
function hoverIn(SELECTED) {
SELECTED.removeEventListener("mouseover", addHIn, false);
}
I have the following code in JS:
if (Subs.Lsr!==null) {
Subs.Measure.Do("markLSRPosts",function() {
Subs.Lsr.Dom($ce);
});
}
Because this kind of code is inside my file multiple times I wanted to create a function for that:
function SingleMeasure(measureTitle, functionName) {
if (setting!==null) {
Subs.Measure.Do(measureTitle,function() {
functionName();
});
}
}
SingleMeasure(Subs.Lsr, "markLSRPosts", Subs.Lsr.Dom($ce));
Now my problem is that the function Subs.Lsr.Dom($ce) is called BEFORE my SingleMeasure()-Function is called (and so always, no matter what the condition of setting is).
I have to admit: This makes sense to me from coding logic. Nonetheless I wonder if there is another way to achieve what I want. (the method ...Dom() only being called when the setting-condition is met)
Now my problem is that the function Subs.Lsr.Dom($ce) is called BEFORE my SingleMeasure()
That's because you are calling it right here: Subs.Lsr.Dom($ce)
SingleMeasure(Subs.Lsr, "markLSRPosts", Subs.Lsr.Dom($ce));
You might pass it as an anonymous function:
SingleMeasure(Subs.Lsr, "markLSRPosts", function() {
Subs.Lsr.Dom($ce);
});
The callback will be invoked by your SingleMeasure function at a later stage.