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
}
});
Related
I use this script to change a class:
$('.fa.fa-plus-circle').each(function() {
$(this).on('click', function () {
$(this).removeClass().addClass("fa fa-minus-circle");
});
});
Then I used
$('.fa.fa-minus-circle').each(function () {
$(this).on('click', function () {
$(this).removeClass().addClass("fa fa-plus-circle");
});
});
So for the first one "fa.fa-plus-circle" that is the default when the page is loading, everything is good and the class changes. But when the class changes I can't do anything else after, JQuery continues to execute
$('.fa.fa-plus-circle').each(function() {
$(this).on('click', function () {
$(this).removeClass().addClass("fa fa-minus-circle");
});
});
Why ??
Thanks in advance
You need to use delegate for this, because you are adding the classes dynamically.
$(document).on("click", '.fa.fa-minus-circle', function() {
$(this).removeClass().addClass("fa fa-plus-circle");
});
$(document).on("click", '.fa.fa-plus-circle', function() {
$(this).removeClass().addClass("fa fa-minus-circle");
});
Also there is no need for looping through the elements for binding the event.
But the recommended approach will be,
$('.fa').click(function() {
$(this).toggleClass("fa-minus-circle fa-plus-circle");
});
Edit
$(document).on("click", ".fa", function() {
$(this).toggleClass("fa-minus-circle fa-plus-circle");
});
It's not .fa-minus-circle when it loads, so the each loop never happens. Even if you removed the each loop (which isn't required) it wouldn't add the listeners because it wouldn't find the selector. So, you have to use the delegates version of on which looks something like this...
$('body').on('click','.fa-minus-circle',function () {
$(this).removeClass().addClass("fa fa-minus-circle");
});
fwiw, you could just use one class and toggleClass Then put all your fa-plus-circle code into the fa class since that is the default behavior.
$('body').on('click','.fa',function () {
$(this).toggleClass("fa-minus-circle");
});
There's a benefit to not removing all classes. There seems no point to removing .fa so that you can add it. Which means that your code should be:
$(function() {
$(document).on("click", '.fa.fa-minus-circle', function() {
$(this).removeClass('fa-minus-circle').addClass("fa-plus-circle");
});
$(document).on("click", '.fa.fa-plus-circle', function() {
$(this).removeClass('fa-plus-circle').addClass("fa-minus-circle");
});
});
And as #AnoopJoshi has pointed out, you can use the .toggleClass() method:
$(function() {
$('.fa').on('click', function() {
$(this).toggleClass('fa-minus-circle fa-plus-circle');
});
});
I'm having troubles with the .bind() and .unbind() features. When the button is clicked, it's supposed to change the color of the box. During this time, the button is disabled by unbinding the click function. However, I'm having issues rebinding the click when the css transition completes.
What I have so far is:
$('button').on('click', function(){
$('button').unbind('click');
$('.box').toggleClass('color');
$('.box').one('webkitTransitionEnd transitionend', function(e){
console.log('transition ended')
$('button').bind('click')
});
});
http://jsfiddle.net/t6xEf/
You need to pass the click handler when binding it. So create a function reference then use it while binding the handler.
function click() {
$('button').off('click.transition');
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').on('click.transition', click)
});
$('button').on('click.transition', click);
Demo: Fiddle
Also look at the usage of namespaces while registering/removing the handler because if there if some other click handler added to the button we don't want to disturb it
Also do not add a event handler inside another one
Also have a look at .one()
function click() {
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').one('click.transition', click)
});
$('button').one('click.transition', click);
Demo: Fiddle
I would use a flag instead of binding/rebinding the event handler:
var animating = false;
$('button').on('click', function() {
if (animating) return;
animating = true;
$('.box').toggleClass('color')
.on('webkitTransitionEnd transitionend', function(e) {
animating = false;
});
});
http://jsfiddle.net/t6xEf/1/
Do not unbind. Use a boolean:
var onTrans = false;
$('button').on('click', toggle);
function toggle() {
if (!onTrans){
$('.box').toggleClass('color');
onTrans = true;
$('.box').on('webkitTransitionEnd transitionend', function (e) {
onTrans = false;
});
}
}
http://jsfiddle.net/jp8Vy/
This is surely not what you want to do. It seems overly complex, and I can't imagine a good use case scenario.
That being said, you need to reattach the functionality to be performed in the final bind statement. You call the function to bind to the click event, but don't tell the function what to attach.
You need something like this:
$('button').bind('click', function() { ... });
However, that probably isn't what you really want. It sounds like you just want to set the button's "disabled" attribute to false, then to true after the animation.
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');
I thought this would work, but whenever I click on the element with the class name of one and it changes to the class named two, I can't get the second event to work. What am I missing here?
//first event
$('.one').on('click', function () {
$('.one').attr('class', 'two');
});
//second event
$('.two').on('click', function () {
$('.two').attr('class', 'one');
});
You need to delegate the event to a static parent..
The problem is , because you seem to dynamically change the class you need to bind the event every single time you change the class.. So delegating it should remove this problem..
Also You can write this as a Single event..
$('body').on('click','.one' , '.two', function() {
if( $(this).hasClass('one'){
function1();
}
else if( $(this).hasClass('two'){
function2();
}
$(this).toggleClass('one two');
});
Why not more simple :) http://jsfiddle.net/XZeNE/1/ or this http://jsfiddle.net/4mJJe/
use API - toggleClass
Further HTML CHange Dmeo http://jsfiddle.net/vuLQK/1/
code
$('.one').on('click', function() {
$(this).toggleClass('two');
});
HTML change
$('.one').on('click', function() {
$(this).toggleClass(function(){
if($(this).hasClass('two'))
$(this).html('NOw its class two HTML HULK');
else
$(this).html('CLASS ONE HTML IRONMAN' );
return "two";
})
});
You should use .on to attach to one of the ancestors of the 2 elements and then use the selector argument to match the event target. The selectors won't match elements that aren't present when the handlers are bound.
$(function () {
$("#container").delegate(".one", "click", function () {
$(this).attr('class', 'two');
});
$("#container").delegate(".two", "click", function () {
$(this).attr('class', 'one');
});
})