Jquery/javascript function issue - javascript

I have a javascript function doing some animation and its parameter is a parent selector.
function myFunction(a)
{
$("'"+a+">#one'").stop(true, true).animate({left:'30px'},1100);
$("'"+a+">#two'").stop(true, true).animate({left:'30px'},1100);
}
and the following line is calling that function.
$("#main").mouseleave(myFunction("#main"));
but this is not working, can anyone tell me whats wrong in my code ?

A couple of issues there:
1. Selectors
Just do the string substitution in your head. If you're passing #main into your function, then your selectors end up looking like this:
$("'#main>#one'")...
Note the ' characters in there. Now, if you remove the ' characters, you'll get:
$("#main>#one")...
...which means "the element with the id "one" that's a child of the element with the id "main". That now works, but it suggests you're using the same id ("one") for more than one element. You cannot do that in HTML.
Your id="one" and id="two" elements should probably have class="one" and class="two" instead, and if so your code should look like this:
function myFunction(a)
{
$(a+">.one").stop(true, true).animate({left:'30px'},1100);
$(a+">.two").stop(true, true).animate({left:'30px'},1100);
}
2. Functions
In your code calling myFunction:
$("#main").mouseleave(myFunction("#main")); // <== Wrong
...you're calling myFunction immediately and passing its return value into mouseleave. Since it has no explicit return value, you end up assing undefined into mouseleave, which won't do anything useful.
If your goal is to have myFunction called when the mouseleave event occurs, you pass in a function reference:
$("#main").mouseleave(function() {
myFunction("#main");
});
It may be worth stepping back from your current task and working through a few basic jQuery (and JavaScript) tutorials, to cement your understanding some of these concepts like ids being unique, passing functions as event handlers, string concatenation, etc.

The mouseLeave function takes a function as a parameter. You're passing in an executed function (one with parameters) so the result of your function is being passed as the parameter to mouseLeave (rather than the function itself).
You need to wrap it another function that would call your myFunction function in a new anonymous function.
Assuming the myFunction piece is correct then you need something like this:
$("#main").mouseleave(new function() {
myFunction("#main");
});

The selector is being concatenated incorrectly. The jquery function takes a String for the selector argument, there is no need to wrap it in single quotes.
function myFunction(a)
{
$(a+">#one").stop(true, true).animate({left:'30px'},1100);
$(a+">#two").stop(true, true).animate({left:'30px'},1100);
}

http://jsbin.com/ifunof/1/edit
function myFunction(a){
$(a+">#one").stop().animate({left:30},1100); // <-- fixed selectors
$(a+">#two").stop().animate({left:30},1100);
}
$("#main").mouseleave(function(){ // <-- (immediate call: Wrong)
myFunction("#main"); // <-- fn reference: OK!
});

Try this -
$(a+" > #one").stop(true, true).animate({left:'30px'},1100);
$(a+" > #two").stop(true, true).animate({left:'30px'},1100);

Well, there are two things wrong in your code:
Your selector becomes "'#main>#one'". This will not select anything. You probably want to omit the apostrophes:
$(a+" > #one")…
But since ids are unique in a document, you won't need the #main prefix anyway. Just use the ids directly:
$("#one, #two").stop(true, true).animate({left:'30px'},1100);
You are calling the function directly (and passing its result, undefined, to the mouseleave method), instead of adding it as an event handler. Instead, use
$("#main").mouseleave(function(e) {
myFunction("#main");
});

Related

Understanding arrow functions - why does this not work and this does?

I am trying to convert all of my older code to use arrow functions...
The following works:
$p_worklist.mouseover (()=> {
closemenues();
console.log ("Show Worklist");
$div_worklistmenu.show();
});
However this does not
$p_worklist.mouseover =()=> {
closemenues();
console.log ("Show Worklist");
$div_worklistmenu.show();
};
The difference is that the first function wraps the body in parens while the second does not but rather replaces the first paren with equals sign and eliminates the second one.
Trying to learn...
Thanks
The first one is calling $p_worklist.mouseover, and passing in a function. Jquery will then do whatever internal code it needs to do to set up the event listener, and when a mouseover happens, it will call the function you gave it.
The second one is assigning to $p_worklist.mouseover, thus overwriting what used to be there with the function you created. No other code is run, and no event listeners are set up.
Jquery's api expects you to call it, so option 1 is the right way to go.
In Your first example You invoke mouseover method, hovewer in next exaple You just overwrite that method and You don't invoke it
The problem is not the arrow function, but your usage of the mouseover attribute to set an event listener.
In JQuery (which, given your use of $, I'm assuming you're using), mouseover is a function that takes another function as an argument. So, you would pass an anonymous arrow function exactly as you do.
In vanilla JavaScript, however, the mouseover attribute is a pointer to the function to be called as an event listener.
If you're using JQ:
$('selector').mouseover(() => {
// ...
});
If you're using JS:
element.mouseover = event => {
// ...
}
Of course, you can override the JQuery method yourself by using the setter, but that's probably not what you're looking for.
mouseover() is a jQuery method. Like all jQuery event-handling methods, it takes the handler function as a parameter, so you have to call the method.
When you assign to $p_worklist.mouseover, you're replacing the method with a new function, not calling the method. That's not how you bind event handlers in jQuery.
You're confusing the jQuery method calls with DOM onXXX properties, where you write something like
element.onmouseover = ()=> {
closemenues();
console.log ("Show Worklist");
$div_worklistmenu.show();
};

What is the purpose of anonymous Functions in Javascript/JQuery when it seems I don't need one?

Let me explain this a little better. I've just started learning JS and Jquery coming from learning java/c for a short while. I'm use to the functions (methods) in those languages and am having a difficult time understanding why certain functions are used in JS. I've read all sorts of tutorials and searched this site but the answers for "why anonymous functions are used" is different than what I'm looking for.
For example:
$(document).ready(function() {
$('div').hide();
});
Here with the use of jquery we are hiding the "div" elements with a function. Or here:
$('div').click(function() {
$('div').hide();
});
The same thing here except when we click on the div it hides it. But here's the thing I'm confused about - why does it need be on click, then a function running ".hide()" as opposed to just every time on click it just does "('div').hide();"
Or with the first piece of code you just want the 'div' elements hidden, why isn't it just simply hiding the elements with $('div').hide() - why is there the need of a function to do this? You don't need to call the function anywhere else. It just hides it when the document is ready, or with the first example, it hides when you click it.
I've seen this in the practice tutorials on codeacademy and other tutorial videos many times so far, where there are functions that I don't think are needed but are used.
Finally, even a function with a variable like this:
$('#add').click(
function() {
var value = $('#inp').val();
$('#shoplist').append('<li>' + value + ' </li>');
}
);
On click it adds a list element to the unordered list, but i don't understand what the need for function() {} is. .click() already makes something happen on click, we run code inside it to happen on click, why does it need a function() as well to make the code inside work?
why does it need be on click, then a function running ".hide()" as opposed to just every time on click it just does "('div').hide();"
You have to pass something to click.
That something is "The function you want to run when the click event happens"
If you instead did:
...click( $('div').hide() )
then you would:
Call hide() immediately (because that is what $('div').hide() does when it is evaluated)
Pass the return value to click.
The return value isn't a function, so it would either error or be ignored, and clicking would do nothing.
The function you pass to click doesn't need to be anonymous, but it does need to be a function.
This would be fine, for example:
function hide_div() {
$('div').hide();
}
...click(hide_div)
The .click function takes a function callback as a parameter. You're telling it what to run when the click event occurs.
You couldn't pass the code inside the anonymous function to the .click function because it is expecting a function callback.
Lines of code are run in functions, and lines of code are executed when they are called on. When you do this .click($('div').hide()), you're calling the function .hide() on $('div'), giving the result of this function to .click(), as opposed to giving this unevaluated line of code to the .click() function. Protip, whenever you see (), some function is executed unless this function is being declared. In this case, .click() is an execution of the function that has been declared as function click(var callback).
There does not exist a single language (that I can think of) where you can actually pass parsed lines of executable code to another function, that are not encapsulated by a method or function. This is simply so because lines of code do not have a type, or definition. How would you define a 'couple of lines of executable code' in a function somewhere?
I challenge you to define a function that does this, and I BET you will either create a function that accepts another function as a parameter, like click(var callback), OR that you will define some sort of parser that tries to parse the lines of code to executable JavaScript and then evaluate it, which is the same as an interpreter, which is what is used to run JavaScript to begin with.

How to call a click( ) attribute?

function dosomething(){
alert($(this).attr('id')+' called with '+$(this).innerHTML);
}
$('#myElement').click(dosomething);
here is the HTML:
<div id="myElement">click me</div>
Clicking the element works. But the following call from another location does not:
dosomething($('#myElement'));
Working with objects in Javascript is still frustrating to me. Can anyone explain WHY #2 doesn't work, and an elegant way to handle both cases? here is a jsfiddle for reference:
http://jsfiddle.net/sqb6bkwr/
Your function dosomething() does not accept any arguments. Therefor it will not work. You can choose to use $('#myElemenet').trigger('click');, or choose to have your function accept an argument which sets the element:
function dosomething(el) {
el = (el) ? el : $(this);
alert(el.attr('id')+' called with '+el.innerHTML);
}
// My suggestion won't work.
// Use dosomething.call(el) instead.
dosomething($('#myElement'));
This doesn't work because the function dosomething() is not expecting the element to be taken in as the first parameter, and passing it as a parameter does not automatically set it as this.
The way you should call that method depends on your intended behavior. If what you want is to just call that dosomething function on that element, then you can do this:
dosomething.call($('#myElement')[0]);
But if your objective is to simulate a click on that element, which would trigger any other click event listeners that may be on that element, then you should do this:
$('#myElement').click();
// or, as #Karl-AndréGagnon pointed out, $('#myElement').trigger('click');
The difference may seem small, but knowing what you really want to happen will probably save you from some headaches down the road.
This is because the this value of your function was not set. You pass an argument to your function, but expect the this value to be the argument.
You should instead call that like this:
dosomething.call($("#myelement")[0]);
This will call the function with the this value of the #myelement. The [0] is there because you want the native DOM element, not a jQuery array-like object. This is why you wrap the this in $(this) in your function.
Try this:
var domething;
$(document).ready(function(){
dosomething = function(elem){
alert(elem.attr('id')+' called with '+elem.attr('title'));
}
$('#myElement').click(function(){
dosomething($(this));
});
});
Working fiddle: http://jsfiddle.net/robertrozas/3z0pg9b1/1/

Event in a function with jQuery

I know how to use events with jQuery in the classical way for example:
$("#moveArea").mousemove(function(event){
$("#info").empty().append("pageX is: "+event.pageX);
});
Demo: http://jsfiddle.net/Ey7kP/
My question is how to pass the event in a function I have already create. I need something like the following, but I don't know how to achieve this
function cursorPos(event) {
$("#info").empty().append("pageX is: "+event.pageX);
}
$("#moveArea").mousemove(cursorPos(event));
Just do
$("#moveArea").mousemove(cursorPos);
Since you're referring to the function and not calling it, there's no need for passing the arguments. jQuery will call it for you and pass event to it.
You dont have to pass any event variable. jQuery will pass it when it executes the handlers. Just say.
$("#moveArea").mousemove(cursorPos);
There's no need to pass the argument as it is defaulted to event. By placing the function name itself, cursorPos within your mousemove() event, you are capturing the necessary event thus rendering the need to pass the argument unnecessary.
function cursorPos(event){
$("#info").empty().append("pageX is: "+event.pageX);
}
$("#moveArea").mousemove(cursorPos);
Working example: http://jsfiddle.net/8v4uE/

jQuery - passing id element to a non-anonymous callback function without using an anonymous function

I'm trying to pass an element's id to storePair
$("#someid").click(storePair($(this).val(),$(this).attr("id"));
using $(this) doesn't work. no value.
Another stackoverflow post suggests that I use an anonymous function as a wrapper for StorePair(val,id), i.e.,
$("#someid").click(function(){storePair($(this).val(),$(this).attr("id")});
That seems kind of roundabout... Is there a way to call StorePair and pass the value and id without using the anon function?
You can use this inside the storePair function to get what you're after, like this:
function storePair() {
var val = $(this).val();
var id = this.id;
//do stuff
}
Then bind it like this:
$("#someid").click(storePair);
Or, use an anonymous function like you already have, round-about or not, it's the way it works :)
It's not a roundabout, it's supposed to work that way. The click function (and any of the binding function cousins) accept a function object to be evaluated when the event triggers.
You are evaluating the function storePair when defining the callback, so it won't work.
use the event data?
var someId = $("#someid");
someId.bind("click",
{ value : someId.val(), id: someId.attr("id") },
storePair);
but you have access to the element that raised the event inside of storePair through event.target, so you can wrap this in $() and get values inside the function

Categories

Resources