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.
Related
$("#button1").click(function(e)
{
//action
});
$("#button2").click(function(e)
{
//do something
$("#button1").click(function(f)
{
//do something else
});
});
I have two buttons doing different actions.but if button 2 is clicked,i need button 1 to do a different task on the next click without the first function being executed.
any suggestions?
For that ,you need to use one variable scope for detect whether button 1 or 2 is click
var btn = 1; // default
$("#button1").click(function(e)
{
if(btn){
#button1 click
}
else{
#after button2 click
}
});
$("#button2").click(function(e)
{
btn = 2; //change value after button2 click
});
I suggest you look into jQuery's .on() and .off() capabilities.
http://api.jquery.com/on/
http://api.jquery.com/off/
As it says in the 'off' link above, you can create namespaces for your click events, so you can add and remove just the particular on and off events you like. Something like this:
$("#button1").on("click.myName", function(e){
//action
});
$("#button2").click(function(e){
//do something
$("#button1").off("click.myName").on("click.myOtherName", function(e) {
//do something else
});
});
This allows you to target your click events more directly, and not call .off() generically, wiping out all click events.
One method you could use is by unbinding any event listener before adding a new event listener to the button you want to change.
This can be done with the on() and off() functions in Jquery.
$("#button1").off('click').on('click',function(e)
{
//action
});
You can then do the same thing with button 2...
$("#button2").off('click').on('click',function(e)
{
//action
$("#button1").off('click').on('click',function(e)
{
//action
});
});
By doing this, the last on click that you set is the only one that will occur when you click that element.
You may try this once
$("#button1").click(function(e)
{
//action
});
$("#button2").click(function(e)
{
//do something
$("#button1").unbind();
$("#button1").bind('click', function(f)
{
//do something else
});
});
I hope this would work for you.
$('#clickableElement').bind({
mousedown: function(e)
{
console.log('mousedown on element');
$(document).bind('mouseup',function(e){
console.log('mouseup caught');
//Do some magic here
$(this).unbind('mouseup');
});
},
mouseup:function(e)
{
//mouseup within element, no use here.
}
});
I'm trying to catch the mouseup event from a mousedown that's released inside or outside of an element. This code almost works, but the problem is the unbind('mouseup') which is unbinding other scripts attached to the mouseup event (jqueryui). If unbind() is not set then the code gets stacked within mouseup event and called x number of times, where x is the times you've mousedowned.
Route 1: is there some kind of self destructing function that calls itself once and destroys?
Route 2: any way to copy/clone the mouseup function prior to inserting the code, then unbind, then set as previous?
Ideally I'd like to keep this code structure for neatness as I have lots of clickable elements, so binding the document.mouseup outside of element.mousedown would be messy.
Here's the Fiddle I forgot to add http://jsfiddle.net/9gFNk/
Can giv your click event a namespace so only that namespaced event gets unbound, and not any others
$(document).on('mouseup.clickableElement',function(e){
console.log('mouseup caught');
//Do some magic here
$(this).off('mouseup.clickableElement');
});
I created a global object to catch mouse events from the document. It's currently set for mouseup only but can be easily expanded for others. The mouseup code is still customizable within the mousedown functions of the clickable elements so it this handy if you have lots of clickable things like I do.
var MouseCatcher=function()
{
this.init=function()
{
var mc = this;
$(document).bind({
mouseup:function(e)
{
mc.mouseup();
}
});
}
this.mouseup=function()
{
return false;
}
}
var mouseCatcher = new MouseCatcher();
mouseCatcher.init();
$('#clickableElement').bind({
mousedown: function(e)
{
console.log('mousedown on element');
mouseCatcher.mouseup=function()
{
console.log('mouseup called from MouseCatcher');
this.mouseup = function(){return false;}
}
},
mouseup:function(e)
{
//mouseup within element, no use here.
}
});
With "on" event its possible, its may not be an exact solution. Please refer this code
$(document).on('mousedown', function() {
$('#clickableElement').css('display', 'none');
$(document).bind('mouseup', function() {
$('#clickableElement').css('display', 'block');
});
});
http://jsfiddle.net/9gFNk/13/
I have this situation: http://jsfiddle.net/Lm7ac/4/
$(".more").hide();
$(document).on("click", ".btn",function() {
alert("hello");
});
$(document).on("click", "div.post",function() {
var morediv = $(this).find(".more");
morediv.slideToggle('fast');
});
I need to keep ".more" closed(or open) when click in ".btn".
How can i do that?
Thanks
Use event.stopPropagation():
$(document).on("click", ".btn",function(event) {
event.stopPropagation();
alert("hello");
});
...note the event argument to the callback, make sure to include it as above.
http://jsfiddle.net/KJ5Uv/
Cheers
Just return false at the end of the .btn click event handler.
$(document).on("click", ".btn",function() {
alert("hello");
return false;
});
When you return false in a jQuery event handler it's like calling event.preventDefault() as well as event.stopPropagation() at the same time.
Here is a demo: http://jsfiddle.net/Lm7ac/5/
Docs for event.preventDefault(): http://api.jquery.com/event.preventDefault/
Docs for event.stopPropagation(): http://api.jquery.com/event.stopPropagation/
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
}
});
I have an anchor tag on my page, I want an event attached to it, which will fire when the display of this element change.
How can I write this event, and catch whenever the display of this element changes?
This is my way of doing on onShow, as a jQuery plugin. It may or may not perform exactly what you are doing, however.
(function($){
$.fn.extend({
onShow: function(callback, unbind){
return this.each(function(){
var _this = this;
var bindopt = (unbind==undefined)?true:unbind;
if($.isFunction(callback)){
if($(_this).is(':hidden')){
var checkVis = function(){
if($(_this).is(':visible')){
callback.call(_this);
if(bindopt){
$('body').unbind('click keyup keydown', checkVis);
}
}
}
$('body').bind('click keyup keydown', checkVis);
}
else{
callback.call(_this);
}
}
});
}
});
})(jQuery);
You can call this inside the $(document).ready() function and use a callback to fire when the element is shown, as so.
$(document).ready(function(){
$('#myelement').onShow(function(){
alert('this element is now shown');
});
});
It works by binding a click, keyup, and keydown event to the body to check if the element is shown, because these events are most likely to cause an element to be shown and are very frequently performed by the user. This may not be extremely elegant but gets the job done. Also, once the element is shown, these events are unbinded from the body as to not keep firing and slowing down performance.
You can't get an onshow event directly in JavaScript. Do remember that the following methods are non-standard.
IN IE you can use
onpropertychange event
Fires after the property of an element
changes
and for Mozilla
you can use
watch
Watches for a property to be assigned
a value and runs a function when that
occurs.
You could also override jQuery's default show method:
var orgShow = $.fn.show;
$.fn.show = function()
{
$(this).trigger( 'myOnShowEvent' );
orgShow.apply( this, arguments );
return this;
}
Now just bind your code to the event:
$('#foo').bind( "myOnShowEvent", function()
{
console.log( "SHOWN!" )
});
The code from this link worked for me: http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
$('#foo').on('show', function() {
console.log('#foo is now visible');
});
$('#foo').on('hide', function() {
console.log('#foo is hidden');
});
However the callback function gets called first and then the element is shown/hidden. So if you have some operation related to the same selector and it needs to be done after being shown or hidden, the temporary fix is to add a timeout for few milliseconds.