jQuery: Can't cache onclick handler? - javascript

I've got a step-by-step wizard kind of flow where after each step the information that the user entered for that step collapses down into a brief summary view, and a "Go back" link appears next to it, allowing the user to jump back to that step in the flow if they decide they want to change something.
The problem is, I don't want the "Go Back" links to be clickable while the wizard is animating. To accomplish this I am using a trick that I have used many times before; caching the onclick handler to a different property when I want it to be disabled, and then restoring it when I want it to become clickable again. This is the first time I have tried doing this with jQuery, and for some reason it is not working. My disabling code is:
jQuery.each($("a.goBackLink"), function() {
this._oldOnclick = this.onclick;
this.onclick = function() {alert("disabled!!!");};
$(this).css("color", "lightGray ! important");
});
...and my enabling code is:
jQuery.each($("a.goBackLink"), function() {
this.onclick = this._oldOnclick;
$(this).css("color", "#0000CC ! important");
});
I'm not sure why it's not working (these are good, old-fashioned onclick handlers defined using the onclick attribute on the corresponding link tags). After disabling the links I always get the "disabled!!!" message when clicking them, even after I run the code that should re-enable them. Any ideas?
One other minor issue with this code is that the css() call to change the link color also doesn't appear to be working.

I wouldn't bother swapping around your click handlers. Instead, try adding a conditional check inside of the click handler to see if some target element is currently animating.
if ($('#someElement:animated').length == 0)
{
// nothing is animating, go ahead and do stuff
}

You could probably make this a bit more concise but it should give you an idea... Havent tested it so watch your console for typeos :-)
function initBack(sel){
var s = sel||'a.goBackLink';
jQuery(s).each(function(){
var click = function(e){
// implementation for click
}
$(this).data('handler.click', click);
});
}
function enableBack(sel){
var s = sel||'a.goBackLink';
jQuery(this).each(function(){
var $this = jQuery(this);
if(typeof $this.data('handler.click') == 'function'){
$this.bind('goBack.click', $this.data('handler.click'));
$this.css("color", "lightGray ! important");
}
});
}
function disableBack(sel){
var s = sel||'a.goBackLink';
jQuery(s).each(function(){
var $this = jQuery(this);
$this.unbind('goBack.click');
$this.css("color", "#0000CC ! important");
});
}
jQuery(document).ready(function(){
initBack();
jQuery('#triggerElement').click(function(){
disableBack();
jQuery('#animatedElement').animate({/* ... */ }, function(){
enableBack();
});
});
});

Related

jQuery continuously running an event

I have the following code which checks for the id of the active tab BUT only once when the page initially loads.
jQuery(document).ready(function(){
var id_of_tab = jQuery('#member-registration .tab-pane.active').attr('id');
console.log(id_of_tab);
});
I need this code to continuously check for the id of the active tab, (as there are various ways in which the user can make this tab active, and I have tried many click and hover events but ive found issues with all of them).
Rather than firing on a click/hover (such as the example below) the code needs to simple needs to keep running and to change the variable value if the active tab changes.
jQuery(document).ready(function(){
$( ".view-registration" ).hover(
function() {
var id_of_tab = jQuery('#member-registration .tab-pane.active').attr('id');
console.log(id_of_tab);
});
});
I'm struggling on this one!
You can bind multiple events on one function handler.
The 4 I suggest here are only suggestion for the code example`
It's up to you to determine the right events to bind.
See list here: http://www.quirksmode.org/dom/events/
$(document).ready(function(){
$( "#member-registration" ).bind("change mouseover click input",function(){
var id_of_tab = $(this).attr('id'); // Will alway return #member-registration
console.log(id_of_tab);
// Suggested console message ;)
console.log("An event occured on #member-registration");
// Maybe a check for the `active` class?
if( $(this).hasClass("active") ){
console.log("#member-registration is active.");
}
});
});

How defined in jQuery was it a regular click on the same element or double-click?

How can I define in jQuery was it a regular click on the same element or double-click?
For example we have element like this:
<div id="here">Click me once or twice</div>
And we need to perform different actions after regular click and double-click.
I tried something like this:
$("#here").dblclick(function(){
alert('Double click');
});
$("#here").click(function(){
alert('Click');
});
But, of course, it doesn't work, everytime works only 'click'.
Then, some people showed me this:
var clickCounter = new Array();
$('#here').click(function () {
clickCounter.push('true');
setTimeout('clickCounter.pop()', 50);
if (clickCounter.length > 2) {
//double click
clickCounter = new Array(); //drop array
} else {
//click
clickCounter = new Array(); //drop array !bug ovethere
}
});
Here we tried to set the interval between clicks, and then keep track of two consecutive events, but this have one problem.. it doesn't work too.
So, someone knows how to do this? or can someone share a link to the material, where I can read about it?
From QuirksMode:
Dblclick
The dblclick event is rarely used. Even when you use it, you should be
sure never to register both an onclick and an ondblclick event handler
on the same HTML element. Finding out what the user has actually done
is nearly impossible if you register both.
After all, when the user double–clicks on an element one click event
takes place before the dblclick. Besides, in Netscape the second click
event is also separately handled before the dblclick. Finally, alerts
are dangerous here, too.
So keep your clicks and dblclicks well separated to avoid
complications.
(emphasis mine)
What you are doing in your question, is exactly how it should be done.
$(".test").click(function() {
$("body").append("you clicked me<br />");
});
$(".test").dblclick(function() {
$("body").append("you doubleclicked me<br />");
});
It works and here is an demo for that.
Since, you want to detect separate single double click. There is a git project for this.
$("button").single_double_click(function () {
alert("Try double-clicking me!")
}, function () {
alert("Double click detected, I'm hiding")
$(this).hide()
})
It adds up events to detect single double clicks.
Hope it helps you now.

JQuery - What can I do to make this work?

http://jsfiddle.net/piezack/X8D4M/5/
I need the change created by clicking the button to be detected. At the moment you have to click inside the field and then outside for it to detect any change.
Thanks guys.
The code for the button CANNOT be altered. Good tries so far though.
Was overcomplicating things. Answer http://jsfiddle.net/piezack/X8D4M/56/
Example using trigger:
//waits till the document is ready
$(document).ready(function() {
$('button.butter').click(function() {
var $form6 = $('#FormCustomObject6Name');
$form6.val('Text has changed');
$form6.trigger('change')
});
$('#FormCustomObject6Name').change(function() {
var x = $('#FormCustomObject6Id').val();
$("a").filter(function() {
return this.href = 'http://www.msn.com'
}).attr('href', 'http://www.google.com/search?q=' + x);
alert(x);
});
});
i think that jmar has the right idea...if i understand correctly you want to be able to type whatever in the box and without clicking out of it to have the button change it to the text has changed.
i dont know if that alert is really necessary, but you can do this if the alert is not needed:
http://jsfiddle.net/X8D4M/24/
To trigger the change event simply add a .trigger after setting the value.
Also, you're selector for the link wasn't working so I just changed it to #link.
http://jsfiddle.net/X8D4M/22/

jQuery Slide in and out

im trying to get a div to slide down on click, which works perfectly, but when clicking the button again, i want to to be hidden, maybe with slideUp()... However im not quite sure how to do it... Any help would be appreciated...
var iJob = this;
this.init = function () {
//Hook up My Page
$("#open-mypage").one("click", iJob.onMyPageDisplayJquery);
//Hook click event on all "mere om.."
/*$('.more-jobs').one("click", iJob.onJobCategoryMoreInfoJquery);
$('#more-wrapper .close').bind("click", iJob.onJobCategoryMoreHideJquery);*/
};
//Vis Min Side
this.onMyPageDisplayJquery = function (event) {
event.preventDefault();
//iJob.jobCategoryMoreHideJquery();
$("#mypage-result").addClass("hidden");
$("#mypage-li").removeClass("mypage-li").addClass("mypage-li-hover");
$('#mypage-info').slideDown('fast', function () {
// Load content with ajax
return false;
});
};
As you can see, slideDown works fine, and the div is displayed - However clicking on the button again it should be hidden... I've tried this, slideToggle(), without any luck
//Vis Min Side
this.onMyPageDisplayJquery = function (event) {
event.preventDefault();
//iJob.jobCategoryMoreHideJquery();
$("#mypage-result").addClass("hidden");
$("#mypage-li").removeClass("mypage-li").addClass("mypage-li-hover");
$('#mypage-info').slideToggle('fast', function () {
////Animation complete
});
};
Have you looked at the JQueryUI Accordion?
I think this might do what you want already?
slideToggle should work. I would suggest it's probably because you're not reversing the other actions you're taking... e.g:
$("#mypage-result").addClass("hidden");
$("#mypage-li").removeClass("mypage-li").addClass("mypage-li-hover");
Should be flipped to...
$("#mypage-result").removeClass("hidden");
$("#mypage-li").removeClass("mypage-li-hover").addClass("mypage-li");
...when clicked again.
The problem is you are using the one function to bind the click handler, which will only ever fire once. Change it to use bind.

Add click event to Div and go to first link found

I think I've been too much time looking at this function and just got stuck trying to figure out the nice clean way to do it.
It's a jQuery function that adds a click event to any div that has a click CSS class. When that div.click is clicked it redirects the user to the first link found in it.
function clickabledivs() {
$('.click').each(
function (intIndex) {
$(this).bind("click", function(){
window.location = $( "#"+$(this).attr('id')+" a:first-child" ).attr('href');
});
}
);
}
The code simply works although I'm pretty sure there is a fairly better way to accomplish it, specially the selector I am using: $( "#"+$(this).attr('id')+" a:first-child" ). Everything looks long and slow. Any ideas?
Please let me know if you need more details.
PS: I've found some really nice jQuery benchmarking reference from Project2k.de here:
http://blog.projekt2k.de/2010/01/benchmarking-jquery-1-4/
Depending on how many of these div.click elements you have, you may want to use event delegation to handle these clicks. This means using a single event handler for all divs that have the click class. Then, inside that event handler, your callback acts based on which div.click the event originated from. Like this:
$('#div-click-parent').click(function (event)
{
var $target = $(event.target); // the element that fired the original click event
if ($target.is('div.click'))
{
window.location.href = $target.find('a').attr('href');
}
});
Fewer event handlers means better scaling - more div.click elements won't slow down your event handling.
optimized delegation with jQuery 1.7+
$('#div-click-parent').on('click', 'div.click', function () {
window.location.href = $(this).find('a').attr('href');
});
Instead of binding all the clicks on load, why not bind them on click? Should be much more optimal.
$(document).ready(function() {
$('.click').click(function() {
window.location = $(this).children('a:first').attr('href');
return false;
});
});
I would probably do something like;
$('.click').click(function(e){
window.location.href = $(this).find('a').attr('href');
});

Categories