Suppose handler of event listener can be added multiple times like below:
firstPar.addEventListener("click", myFirstEventHandler, false);
firstPar.addEventListener("click", mySecondEventHandler, false);
etc...
So, how can I combine the code so that I could use by shortening:
function allHandler(){
myFirstEventHandler();
mySecondEventHandler();
}
or,
function allHandler(){
return function(){
myFirstEventHandler();
mySecondEventHandler();
}
}
So that I could use:
firstPar.addEventListener("click",allHandler,false);
Or, the other way?
The first way is fine but I would include the event:
function myFirstEventHnadler (event) {
event.stopPropagation(); // To answer your question in the comments.
}
function mySecondEventHandler (event) {
}
function allHandler(event){
myFirstEventHandler(event);
mySecondEventHandler(event);
}
Demo: http://jsfiddle.net/aUE2L/
This may introduce scoping complexities, but why not use an anonymous function.
firstPar.addEventListener("click", function(){
myFirstEventHandler();
mySecondEventHandler();
}, false);
Related
So I have something like:
$('#friendRequests').on('click', '.acceptFriendRequest', function (event) {
// code here
}
How could I make the click of .denyFriendRequest to run that same function above, and to know which button was clicked (to decide whether to accept or deny the request in my backend)
Thank you
Use Multiple Selector (“selector1, selector2, selectorN”) to bind event to multiple elements and use this, $(this) or this.target to refer to current element.
Live Demo
$('#friendRequests').on('click', '.acceptFriendRequest, .denyFriendRequest', function (event) {
alert(this.className);
//alert($(this).attr('class');
//alert(event.target.className);
});
If you expect the element to have multiple classes and you need if one of classes would be .acceptFriendRequest or .denyFriendRequest then you can use .hasClass()
$('#friendRequests').on('click', '.acceptFriendRequest, .denyFriendRequest', function (event) {
if($this).hasClass('acceptFriendRequest')
{
}
if($this).hasClass('denyFriendRequest')
{
}
});
try using jquery hasClass():
$('#friendRequests').on('click', function (event) {
if ($(this).hasClass("acceptFriendRequest")) {
//
} else if ($(this).hasClass("denyFriendRequest")) {
//
} else {
//
}
}
You can do this:
$('#friendRequests').on('click', '[class$="FriendRequest"]', function (event) {
console.log(event.target.className);
}
I'm wondering if I can fire off both of these events together :
$("input[type=checkbox]").click(function(){
if($(this).is(":checked"))
{
//Value of checkbox
alert(this.value);
}
});
and
$("input[type= 'text']").keyup(function(){
alert(this.value);
});
I looked into .bind, but that seems to only work for one selected elements (i.e. $(p).bind("mouseout mouseenter).doSomething()).
The situation I am running into is that I have a function that needs to fire anytime either one of these things occur.
Try
$("input[type=checkbox],input[type='text']").on('click keyup', function(){
// code
});
Two ways you can achieve this as shown below:
using "on" method:
$(document).on('keyup click',"input[type=checkbox],input[type='text']", function(){
// Do stuff here..
})
Call function after the event.
$("input[type=checkbox]").click(doSomething);
$("input[type= 'text']").keyup(doSomething);
function doSomething() {
}
If you still need the additional if, you can use:
$("input[type=checkbox]").click(function(){
if($(this).is(":checked"))
{
//Value of checkbox
alert(this.value);
somethingHappened();
}
});
$("input[type= 'text']").keyup(function(){
alert(this.value);
somethingHappened();
});
function somethingHappened() {
// Do stuff
}
Perhaps all you need is a common function?
$("input[type=checkbox]").click(function(){
if($(this).is(":checked")) {
special(this.value);
}
});
$("input[type= 'text']").keyup(function(){
special(this.value);
});
function special(val) {
alert(val);
}
If your intent really is to invoke a function when any checkboxes/text fields across the whole page changes, you probably want something like this:
$('body').on('change', ':checkbox,:text', function () {
});
Note that the :checkbox and :text selectors are much nicer than input[type=checkbox] etc.
I have a bunch of elements that get three different classes: neutral, markedV and markedX. When a user clicks one of these elements, the classes toggle once: neutral -> markedV -> markedX -> neutral. Every click will switch the class and execute a function.
$(document).ready(function(){
$(".neutral").click(function markV(event) {
alert("Good!");
$(this).addClass("markedV").removeClass("neutral");
$(this).unbind("click");
$(this).click(markX(event));
});
$(".markedV").click(function markX(event) {
alert("Bad!");
$(this).addClass("markedX").removeClass("markedV");
$(this).unbind("click");
$(this).click(neutral(event));
});
$(".markedX").click(function neutral(event) {
alert("Ok!");
$(this).addClass("neutral").removeClass("markedX");
$(this).unbind("click");
$(this).click(markV(event));
});
});
But obviously this doesn't work. I think I have three obstacles:
How to properly bind the changing element to the already defined function, sometimes before it's actually defined?
How to make sure to pass the event to the newly bound function [I guess it's NOT accomplished by sending 'event' to the function like in markX(event)]
The whole thing looks repetitive, the only thing that's changing is the alert action (Though each function will act differently, not necessarily alert). Is there a more elegant solution to this?
There's no need to constantly bind and unbind the event handler.
You should have one handler for all these options:
$(document).ready(function() {
var classes = ['neutral', 'markedV', 'markedX'],
methods = {
neutral: function (e) { alert('Good!') },
markedV: function (e) { alert('Bad!') },
markedX: function (e) { alert('Ok!') },
};
$( '.' + classes.join(',.') ).click(function (e) {
var $this = $(this);
$.each(classes, function (i, v) {
if ( $this.hasClass(v) ) {
methods[v].call(this, e);
$this.removeClass(v).addClass( classes[i + 1] || classes[0] );
return false;
}
});
});
});
Here's the fiddle: http://jsfiddle.net/m3CyX/
For such cases you need to attach the event to a higher parent and Delegate the event .
Remember that events are attached to the Elements and not to the classes.
Try this approach
$(document).ready(function () {
$(document).on('click', function (e) {
var $target = e.target;
if ($target.hasClass('markedV')) {
alert("Good!");
$target.addClass("markedV").removeClass("neutral");
} else if ($target.hasClass('markedV')) {
alert("Bad!");
$target.addClass("markedX").removeClass("markedV");
} else if ($target.hasClass('markedX')) {
alert("Ok!");
$target.addClass("neutral").removeClass("markedX");
}
});
});
OR as #Bergi Suggested
$(document).ready(function () {
$(document).on('click', 'markedV',function (e) {
alert("Good!");
$(this).addClass("markedV").removeClass("neutral");
});
$(document).on('click', 'markedX',function (e) {
alert("Bad!");
$(this).addClass("markedX").removeClass("markedV");
});
$(document).on('click', 'neutral',function (e) {
alert("Ok!");
$(this).addClass("neutral").removeClass("markedX");
});
});
Here document can be replaced with any static parent container..
How to properly bind the changing element to the already defined function, sometimes before it's actually defined?
You don't bind elements to functions, you bind handler functions to events on elements. You can't use a function before it is defined (yet you might use a function above the location in the code where it was declared - called "hoisting").
How to make sure to pass the event to the newly bound function [I guess it's NOT accomplished by sending 'event' to the function like in markX(event)]
That is what happens implicitly when the handler is called. You only need to pass the function - do not call it! Yet your problem is that you cannot access the named function expressions from outside.
The whole thing looks repetitive, the only thing that's changing is the alert action (Though each function will act differently, not necessarily alert). Is there a more elegant solution to this?
Yes. Use only one handler, and decide dynamically what to do in the current state. Do not steadily bind and unbind handlers. Or use event delegation.
Its possible to clear jquery one property? for example given html
<div id="button">button</div>
<div id="clearOneProperty">clear one property</div>
and js
$("#button").one("click", function () {
alert("blah");
});
$("#clearOneProperty").on("click", function () {
// clear "one" property, that is after this event, I want "#button" to work again
});
Demo http://jsfiddle.net/RzzCu/2/
So, if click #button div, alert happened only one times right?
And I want that, at click on #clearOneProperty, reset one property. Its possible?
P.S. I am not asking how to make this with other ways, I am interest exact: "possible clear jquery one method?". Thanks.
Try this:
function bindButton() {
$("#button").unbind('click').one("click", function() {
alert("blah");
});
}
bindButton();
$("#clearOneProperty").on("click", function() {
bindButton();
});
Updated fiddle
The one unbinds its self on first invocation as stated "The first form of this method is identical to .bind(), except that the handler is unbound after its first invocation", jQuery Documentation *So you need to bind it again*.
Live Demo
$("#button").one("click", onefunction);
function onefunction() {
alert("blah");
}
$("#clearOneProperty").one("click", function() {
$("#button").one("click", onefunction);
});
Just rebind it inside the function.
$("#button").one("click", function () {
alert("blah");
});
$("#clearOneProperty").one("click", function () {
$('#button').one("click", function () {
alert("blah");
});
});
here a fiddle
Use unbind() method
$("#button").unbind();
Try
$('#button').unbind('click');
Can hover and click functions be combined into one, so for example:
click:
$('#target').click(function() {
// common operation
});
hover:
$('#target').hover(function () {
// common operation
});
can they be combined into one function?
Thanks!
Use basic programming composition: create a method and pass the same function to click and hover as a callback.
var hoverOrClick = function () {
// do something common
}
$('#target').click(hoverOrClick).hover(hoverOrClick);
Second way: use bindon:
$('#target').on('click mouseover', function () {
// Do something for both
});
jQuery('#target').bind('click mouseover', function () {
// Do something for both
});
Use mouseover instead hover.
$('#target').on('click mouseover', function () {
// Do something for both
});
$("#target").hover(function(){
$(this).click();
}).click(function(){
//common function
});
You can use .bind() or .live() whichever is appropriate, but no need to name the function:
$('#target').bind('click hover', function () {
// common operation
});
or if you were doing this on lots of element (not much sense for an IE unless the element changes):
$('#target').live('click hover', function () {
// common operation
});
Note, this will only bind the first hover argument, the mouseover event, it won't hook anything to the mouseleave event.
var hoverAndClick = function() {
// Your actions here
} ;
$("#target").hover( hoverAndClick ).click( hoverAndClick ) ;
You could also use bind:
$('#myelement').bind('click hover', function yourCommonHandler (e) {
// Your handler here
});
i think best approach is to make a common method and call in hover and click events.
$("#target").on({
hover: function(){
//do on mouse hover
},
click: function(){
//do on mouse click
}
});