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/
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();
};
In JavaScript I'm attempting to set an onchange callback that accepts a parameter. However, how I'm currently doing it overrides the event object that is created. I don't actually need the event for my purposes, but I would like to know how I can capture both the event and any passed in parameters in case my needs change.
EDIT: For clarity, this onchange event could be called both programatically and by a user. There may be an instance where I'm creating an empty select element so the user can pick what they want, or creating a populated one based on some other interaction.
EDIT: Also, the below is a simplified example of a much larger code base. Assume that the scoping is not global of any of the variables. I'm really looking for an answer of how to specifically be able to capture both and event object (when called via user interaction) and another object (when called via code). It feels like having the atr parameter mean different things in different contexts is hacky - but I come more from a strongly typed background so it might be just me.
function update(atr) {
...
}
document.getElementById("myelement").onchange = update;
var atr = {"id":1,"param":"val1"};
// This gives me atr in the function as defined above
document.getElementById("myelement").onchange(atr);
// This way, however, gives me atr in the function as the event
document.getElementById("myelement").onchange();
What I would really like is something like this:
function update(e, atr) {
// Now I have e as the event and atr as the value I've passed in
}
document.getElementById("myelement").onchange = update;
var atr = {"id":1,"param":"val1"};
// This gives me atr in the function as defined above
document.getElementById("myelement").onchange(atr);
However the above code doesn't work. I suspect that I have to do something with bind() but as far as I can understand that I would simply be overriding the event's (this) object in the function like I'm doing now implicitly.
The accepted answer in this question Similar Question is basically what I want to do, but that is with React JS and I would like to do this without any frameworks. I've been trying to search for multiple parameters and onchange events and primarily getting React or unrelated responses. Either this is a harder question than I think, or I'm searching for the answer in completely the wrong way.
I will explain what happens in the linked answer as you mentioned that you want to achieve the same behaviour.
So:
<fieldset onChange={(e) => this.props.handleChange("tags", e)}>
This React code attaches anonymous function with one parameter e to the fieldset as onChange listener. This function in its body invokes another function, passing e with additional parameters.
Translating this into your code, you would like to achieve something like this:
function update(e, attr) {
// e is instance of Event
// attr is additional parameter
}
document.getElementById("myelement").onchange((e) => update(e, attr));
// or without ES6 arrow function:
document.getElementById("myelement").onchange(function(e){ update(e, attr); });
Also, be advised that proper way of attaching event listeners is by addEventListner API.
I'm not sure I understand exactly what you're trying to do, but first you need to distinguish between the case that the event is triggered by the user and the case that you call the event programatically, when you call it programatically there is no event.
you can do something like this:
You mentioned that you use select, the logic is that when a change in the select occurs the event is thrown and you get the selected value, in your case the value can be the content of the atr var:
HTML
<select id="myelement" onchange="update(event)">
<option value='{"id":1,"param":"val1"}'>val1
<option value='{"id":2,"param":"val2"}'>val2
</select>
JavaScript
function update(e) {
var atr = JSON.parse(document.getElementById("myelement").value);
//now you have access both to the event and the 'parameter'
}
This covers the case when the event is triggered by the user, when you want to trigger the event programatically, since there is no event, use a different function that take the atr parameter.
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/
I am using jquery to bind an event to a few buttons...
$(".numField").bind("click", stageButtonClick());
In the function stageButtonClick(), I want to get the object of the calling button, but I cannot use $(this) inside the stageButtonClick function, it doesn't return anything for me.
Also, please don't suggest the inline function usage
$(".numField").bind("click", function() {...})
I would like to learn how to do it this way.
Your problem is here:
$(".numField").bind("click", stageButtonClick());
don't use parenthesis ^^
Don't use parenthesis when assigning a named function because it will call the function and assign the result instead.
This works:
Demo
$(document).ready(function(){
$(".numField").bind("click", stageButtonClick);
});
function stageButtonClick()
{
alert( $(this).attr("id") );
}
You are trying to do things in a very un-jQuery way. Even if you don't want the entire function inline you could make your life much easier by doing something like this:
$(".numField").bind("click", function() {
stageButtonClick(this); // or stageButtonClick($(this)) if you want to pass jQuery selector
});
Here you simply pass the clicked DOM element to your stageButtonClick() function.
Also, if you are using jQuery 1.7 or higher, you should really use on() instead of bind().
At first, $(".numField").bind("click", stageButtonClick()); will not work because stageButtonClick() return the result of the stageButtonClick function, not the function itself
Second, an event objet is passed to the called function with a target and currentTarget element. Normaly, the event.currentTarget will be .numField.
So, try with $(".numField").bind("click", stageButtonClick); and you could normally use $(this) or $(event.currentTarget)
If thats the case you can use the event object
$(".numField").bind("click", stageButtonClick);
function stageButtonClick(e){
// You can just use
**this**
OR
**$(e.target)**
}
Also bind the event using .on() instead of .bind() as the later has been superseeded by the former.
$(".numField").on("click", stageButtonClick);
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