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/
Related
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();
};
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");
});
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/
I'm having an issue with a function I'm calling (using jQuery).
My issue is that when I attempt call a function within another function, that first one is not being called. However, when I place the contents of the failed function into the one calling said failed function, the code executes fine. I'll show you what I'm talking about:
$('form.register .submit').click(validateRegister);
function submitStart() {
var $this = $(this);
$this.parent().addClass('processing');
var $processing = $('#processing');
$processing.show();
var $endNote = $this.parent().find('#endNote')
$endNote.slideDown();
}
function validateRegister(){
submitStart();
}
See, when the contents of submitStart() are places into the validateRegister(), they code executes. However, when calling the function as it shows in this code, it fails to work. I've considered scope (at least to my knowledge) to no avail.
Any help is extremely appreciated, thank you!
You're losing your expected this value, so the submitStart is likely getting called, but doesn't work properly.
Do this:
function validateRegister(){
submitStart.call( this );
}
Here you're calling the submitStart method via the .call() method, which is available on function instances.
The .call() method lets you manually set the value of this in the function you're calling.
So because you've assigned validateRegister as the handler, jQuery makes sure the value of this is your element. But since validateRegister is calling another function, it carries the responsibility of making sure that function has the proper this value.
Just keep in mind that when you call any function like this:
someFunction();
...the value of this in that function will be window, unless you manually set it to something else.
var $this = $(this); is returning the window.
this will no longer be referencing the clicked element but will represent window instead. You can change submitStart so that it accepts a parameter and pass this to it.
I think you may have an issue with this not being what you think it is.
Try this:
submitStart.call(this)
The problem here is this. When you use validateRegister as an event hander, jQuery automatically makes sure that this refers to the DOM element that dispatched the event. But when you call your separate function, the scope isn't being set correctly, so this probably refers to the window object (that's the default when you refer to this in the global scope). To fix it, the easiest way would be to pass the element along as an argument:
function submitStart(element) {
var $this = $(element);
$this.parent().addClass('processing');
var $processing = $('#processing');
$processing.show();
var $endNote = $this.parent().find('#endNote')
$endNote.slideDown();
}
function validateRegister(){
// "this" is the DOM element
submitStart(this);
}
As #Andrew noted, you can also set the value of this in submitStart by using the .apply() method of the submitStart 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