How to decide if a parameter is the click event - javascript

I have a function which can be called by either a click event or directly. When I call it directly, I need pass it a data parameter, so I've defined the function to accept a parameter to account for the direct call with the parameter.
function myFunc(param){
}
Within the function, I need to differentiate whether the function was called directly or from the click event, so what I thought I could simply check if param is set. If it's set, then the function is called directly. If it's not set, then it's called from the click event.
The problem is that a click event by default passes an event object. So even when the function is called by the click event, param won't be null.
So is there a way to check whether the param passed is the click event?

You don't need to duplicate any code. The proper way to do this is to handle the click event with an event handler, and the action you want to take in another function. For example:
// define main action
var doSomethingUseful = function(is_clicked) {
// write some code here
}
// define click handler
var myBtnClicked = function(e) {
doSomethingUseful(true);
}
// bind click event
$('#my_button').click(myBtnClicked);
Although, as was already mentioned to you, the fact that you need to know that information is usually a warning sign that there might be a simpler way to do things.
edit for example:
// define main action
var doSomethingUseful = function() {
// write some code here that doesn't care "why" it's being called
}
// define click handler
var myBtnClicked = function(e) {
// do the click-only stuff
// call the generic function
doSomethingUseful();
}
// bind click event
$('#my_button').click(myBtnClicked);

IE's before version 9 don't always pass the event argument, so the parameter will be be undefined if it is called from an IE click.
function myFunc(param){
if(!param) || param.clientX)// not called with a data param
}
You would do better to check for the data than for the event.

Check for the .clientX property that is passed to the click event.
function(param){
if(param.clientX){//this is a click event}
else
{//this is a call event};
};
You may want to use this one.
function(param){
if(param.target){//this is a click event}
else
{//this is a call event};
};

function myFunc(param) {
// which (aka keyCode) is a property set to params
// by jQuery for any event
// Check for object make you free to pass parameter
// as object also with string, array and so on
if (Object.prototype.toString(param) == '[object Object]' && param.which) {
// called by clck
console.log(param.which);
} else {
// called by function
console.log(param);
}
}
$('#clickable').click(myFunc)
// passing parameter as object
myFunc({
a: 'abc',
b: 'def'
});​
// passing parameter as string
myFunc('Hello');
// passing parameter as array
myFunc([1, 2, 2]);
and so on.
DEMO

jQuery(document).ready(function(){
$('#someID').click(function(){
myFunc(true);
});
myFunc();
});
function myFunc(param){
param ? alert("click"):alert("not click");
}

Related

Why does my JavaScript function see a mouseevent instead of an empty variable?

I'm attaching an eventlistener to a button on a page. When clicked, it runs a function.
harvestDataBtn.addEventListener("click", harvestData, false);
The function optionally takes a value.
function harvestData(idsToHarvest)
I don't want the clicking of the button to pass anything into the function. The optional variable idsToHarvest is used in other instances of the function being called, separate from the click.
However, when I click the button, idsToHarvest is a mouseevent. Making this code below inside my function not work as intended.
if ( idsToHarvest ) {
// do something with string
} else {
// button was clicked, do something else
}
You could pass the event listener a function that wraps your desired call to harvestData and ignore the event object that is passed by default:
harvestDataBtn.addEventListener("click", function (e){harvestData();}, false);
el.addEventListener("click", function (event){ ... });
The 2nd param, in this case, a function, expects the argument passed in to be the event object.
If you are using that same function for other purposes and expect the argument to be something else, it won't work as an event handler.
From the spec, it states:
An event listener consists of these fields:
type (a string)
callback (an EventListener)
capture (a boolean, initially false)
passive (a boolean, initially false)
once (a boolean, initially false)
removed (a boolean for bookkeeping purposes, initially false)
As stated, it shows the callback is actually an EventListener, which is defined by the interface shown:
callback interface EventListener {
void handleEvent(Event event);
};
As you can see, when the callback is evaluated and the handleEvent is called, it accepts 1 argument, event of the type Event.

Pragmatically test if specific event handler(function) is bound to an object's event using jQuery

I was looking for method to specifically test if a certain handler(function) was bound to specific object on a specific event.
The problem I am trying to solve is I want to bind a handler to an objects unload event but I wanted a way to test if it was already bound so I did not bind it twice.
Here is a solution that worked for me. I used this stackoverflow answer (https://stackoverflow.com/a/2518441/2512022) to create the following function to test if a object has a specific handler bound to a specific event.
This function take a Object, Event Name, and handler function name as input parameters and will return true/false if the function is bound the event on the object passed in.
function testHandler(obj, sEvent, sHandlerName)
{
var retVal = false;
// Get all events bound to object
var windowEvents = jQ._data(obj, "events");
// Get all handlers for a specific event
var handlers = windowEvents[sEvent];
jQ(handlers).each(function() {
// Using passed name to see if there is a match
if(this.handler.name === sHandlerName)
{
retVal = true;
return;
}
});
return retVal;
}
Then call the function as follows.
// Test if there is a beforeclose() handler bound to the window objects
// "beforeunload" event
testHandler(window, "beforeunload", "beforeclose");
You could even test if there is on anonymous handler attached to an event. In the call below "this" references a button, and we are testing if there is an anonymous hanlder attached to the buttons click event
testHandler(this, "click", "anonymous");

Why must callbacks in jQuery be anonomous?

This works just as expected but I don't like it.
$('#login-form').on('submit', function(event){
event.preventDefault();
init.login();
});
var init = {
login: function() {
// do login stuff
}
};
This is what I want but it does not work.
$('#login-form').on('submit', init.login(event));
var init = {
login: function(event) {
event.preventDefault();
// do login stuff
}
};
Why?
It will work, you're calling the function (the value given as a callback will be the result of the function) rather than passing it as a value
$('#login-form').on('submit', init.login);
init.login(event) calls the function init.login, passing the (non-existent) variable event to it. If you want to pass the function itself as callback, don't call it:
$('#login-form').on('submit', init.login);
You will have to declare that function before you pass it though, at this point init.login is undefined.
You're already calling the function in that line (with undefined, there is no event yet). You need to pass the function itself (not its result):
$('#login-form').on('submit', init.login);
Notice that init.login is still an anonymous function, it has no name :-) Also beware that the method is called with this being the login form element, not the init object. If you needed that, you'd use .on('submit', init.login.bind(init)).

onclick call with params

I've got a function, like this:
menu[0].onclick = function() {
filters.reset_all();
clients.get();
}
So it's called when user clicks on the first menu element. Now I need to call it form the other place and what I've done is this:
if (li.onclick) { //li and menu[0] above are the same
li.onclick.call();
}
and it works well.
But now I need to pass some params to onclick function. I've tried this .call(some_param); but arguments array in onclick is empty.
What am I doing wrong?
edit: changed into this:
menu[0].onclick = function(arg) {
console.log(arg);
filters.reset_all();
clients.get();
}
and
li.onclick.call(li,param);
still nothing
The first argument to .call() is the value for the this pointer. The 2nd, 3rd, etc... arguments get passed to the function. You only need to use .call() if you're explicitly trying to set the this pointer. Otherwise, you can just directly call the function li.onclick().
Event handlers are generally called by the system and when that happens, they are passed the event object as the first argument. If you want a function available that takes different arguments, you should create your own function for that and not use the event handling function. Your event handler can also call this other function if desired.
menu[0].onclick = function() {
myFunc("aaa");
}
function myFunc(arg1) {
// do whatever here
filters.reset_all();
clients.get();
}
if (li.onclick) {
myFunc("bbb");
}
it should be
call(object, param1, param2, param3...);
In your case you can write
li.onclick.call(li, param1);
The first parameter of call() is the context (in this case this) the rest of the parameters go into the arguments array in order. If you use apply() instead of call then you have just two parameters: apply(this, arguments_array)

jQuery's .click - pass parameters to user function

I am trying to call a function with parameters using jQuery's .click, but I can't get it to work.
This is how I want it to work:
$('.leadtoscore').click(add_event('shot'));
which calls
function add_event(event) {
blah blah blah }
It works if I don't use parameters, like this:
$('.leadtoscore').click(add_event);
function add_event() {
blah blah blah }
But I need to be able to pass a parameter through to my add_event function.
How can I do this specific thing?
I know I can use .click(function() { blah }, but I call the add_event function from multiple places and want to do it this way.
For thoroughness, I came across another solution which was part of the functionality introduced in version 1.4.3 of the jQuery click event handler.
It allows you to pass a data map to the event object that automatically gets fed back to the event handler function by jQuery as the first parameter. The data map would be handed to the .click() function as the first parameter, followed by the event handler function.
Here's some code to illustrate what I mean:
// say your selector and click handler looks something like this...
$("some selector").click({param1: "Hello", param2: "World"}, cool_function);
// in your function, just grab the event object and go crazy...
function cool_function(event){
alert(event.data.param1);
alert(event.data.param2);
}
You need to use an anonymous function like this:
$('.leadtoscore').click(function() {
add_event('shot')
});
You can call it like you have in the example, just a function name without parameters, like this:
$('.leadtoscore').click(add_event);
But the add_event method won't get 'shot' as it's parameter, but rather whatever click passes to it's callback, which is the event object itself...so it's not applicable in this case, but works for many others. If you need to pass parameters, use an anonymous function...or, there's one other option, use .bind() and pass data, like this:
$('.leadtoscore').bind('click', { param: 'shot' }, add_event);
And access it in add_event, like this:
function add_event(event) {
//event.data.param == "shot", use as needed
}
If you call it the way you had it...
$('.leadtoscore').click(add_event('shot'));
...you would need to have add_event() return a function, like...
function add_event(param) {
return function() {
// your code that does something with param
alert( param );
};
}
The function is returned and used as the argument for .click().
I had success using .on() like so:
$('.leadtoscore').on('click', {event_type: 'shot'}, add_event);
Then inside the add_event function you get access to 'shot' like this:
event.data.event_type
See the .on() documentation for more info, where they provide the following example:
function myHandler( event ) {
alert( event.data.foo );
}
$( "p" ).on( "click", { foo: "bar" }, myHandler );
Yes, this is an old post. Regardless, someone may find it useful. Here is another way to send parameters to event handlers.
//click handler
function add_event(event, paramA, paramB)
{
//do something with your parameters
alert(paramA ? 'paramA:' + paramA : '' + paramB ? ' paramB:' + paramB : '');
}
//bind handler to click event
$('.leadtoscore').click(add_event);
...
//once you've processed some data and know your parameters, trigger a click event.
//In this case, we will send 'myfirst' and 'mysecond' as parameters
$('.leadtoscore').trigger('click', {'myfirst', 'mysecond'});
//or use variables
var a = 'first',
b = 'second';
$('.leadtoscore').trigger('click', {a, b});
$('.leadtoscore').trigger('click', {a});
$imgReload.data('self', $self);
$imgReload.click(function (e) {
var $p = $(this).data('self');
$p._reloadTable();
});
Set javaScript object to onclick element:
$imgReload.data('self', $self);
get Object from "this" element:
var $p = $(this).data('self');
I get the simple solution:
<button id="btn1" onclick="sendData(20)">ClickMe</button>
<script>
var id; // global variable
function sendData(valueId){
id = valueId;
}
$("#btn1").click(function(){
alert(id);
});
</script>
My mean is that pass the value onclick event to the javascript function sendData(), initialize to the variable and take it by the jquery event handler method.
This is possible since at first sendData(valueid) gets called and initialize the value. Then after jquery event get's executed and use that value.
This is the straight forward solution and For Detail solution go Here.
Since nobody pointed it out (surprisingly). Your problem is, that $('.leadtoscore').click(add_event); is not the same as $('.leadtoscore').click(add_event('shot'));. The first one passes a function, the second a function invocation so the result of that function is passed to .click() instead. That's not what you want. Here's what you want in vanilla JavaScript terms:
$('.leadtoscore').click(add_event.bind(this, 'shot'));
Function.prototype.bind() passes the function to .click() just like in the first example but with bound this and arguments that will be accessible on invocation.

Categories

Resources