How do I unbind another jQuery function on .click()? - javascript

I have this script that run to fix my menu bar to the browser on scroll. Nothing really needs to change here (works as it should). However, you may need it...
var div = $('#wizMenuWrap');
var editor = $('#main_wrapper');
var start = $(div).offset().top;
$(function fixedPackage(){
$.event.add(window, "scroll", function() {
var p = $(window).scrollTop();
$(div).css('position',((p)>start) ? 'fixed' : 'static');
$(div).css('top',((p)>start) ? '0px' : '');
//Adds TOP margin to #main_wrapper (required)
$(editor).css('position',((p)>start) ? 'relative' : 'static');
$(editor).css('top',((p)>start) ? '88px' : '');
});
});
Now for the issue at hand. I have another script function that calls a modal pop-up (which again works as it should). However, it's not slick from a UI perspective when I scroll the page when the modals open. So I want to disable the script above when the modal script below is called. In other words, when I click to open the modal pop-up, the script above shouldn't work.
$(function () {
var setUp = $('.setupButton');
// SHOWS SPECIFIED VIEW
$(setUp).click(function () {
$('#setupPanel').modal('show');
//PREVENTS PACKAGE SELECT FIXED POSITION ON SCROLL
$(setUp).unbind('click',fixedPackage);
});
})
As you can see above, I tried to unbind the scroll function (the first code snippet), but this is not correct.
These two scripts are in two separate js libraries.

I strongly disagree that you ought to be binding and unbinding the event. There's no need! A little logic in your scroll event to check to see if the modal is open should take care of the issue:
$(function fixedPackage(){
$(window).bind("scroll", function() {
// if the modal is displayed, do nothing
if ($('#setupPanel').is(':visible'))
return;
// -- existing code here --
});
});
This way, if the modal element is visible, the code simply stops where it is. Once you hide the element, the code will continue to work as before without having to manage the state of event in some other script... confusing!
Also, as mentioned in some other comments, don't use $.event.add, use the public API method bind
Documentation
jQuery is - http://api.jquery.com/is/
jQuery visible selector - http://api.jquery.com/visible-selector/
jQuery bind - http://api.jquery.com/bind/

When you store a jquery object into a var you can call functions directly:
var setUp = $('.setupButton');
var div = $('#wizMenuWrap');
var editor = $('#main_wrapper');
setUp.click(...);
seTup.unbind(...);
editor.css(...);
div.css(...);

all you need to do is change your script to:
$(function () {
var setUp = $('.setupButton');
// SHOWS SPECIFIED VIEW
$(setUp).bind('click',function () {
$('#setupPanel').modal('show');
//PREVENTS PACKAGE SELECT FIXED POSITION ON SCROLL
$(setUp).unbind('click');
});
})
As explained in the jQuery Docs, Event handlers attached with .bind() can be removed with .unbind() . For more information about bind and unbind:
.bind()
.unbind()

try
$(setUp).unbind('click').die('click')

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 to toggle JQueryUI Draggable on/off in an if statement

I wrote a block of code (below) that toggles JQuery Draggable on/off on an element.
In short , when you click a div called button it toggles the draggable effect on/off on another div called dragBlock
This took me awhile but I finally got it working. The question I have is I don't understand why the code below doesn't work with only one Draggable instance. Mainly the one that uses the state argument.
$(dragBlock ).draggable(state);
Instead it only works when I use this:
$(dragBlock ).draggable(state);
$(dragBlock ).draggable(); // This line is needed for the code to work. Why?
This isn't a big issue but I would like to know why this is and I figure someone here might be able to explain it. JSfiddle is here:
And the code is below:
$(document).ready(function() {
var state = "disable";
var button = document.getElementById("button");
var dragBlock = document.getElementById("dragBlock");
var toggle = function() {
if (state==="enable") {
state = "disable";
}
else if(state==="disable") {
state = "enable";
}
$(dragBlock ).draggable(state);
$(dragBlock ).draggable(); // This line is needed for the code to work. Why?
console.log(state);
};
button.addEventListener("click", toggle, false);
});
You should really have the .draggable() outside the event handler, and only the .draggable(state) inside.
Calling .draggable() is how you initially setup the draggable functionality on the element.
Calling .draggable('enable') or .draggable('disable') is a way to enable or disable an already-configured draggable element. It's a way to interact with a draggable element that you've already setup.
Note though, that by calling draggable() outside the event handler your default initial state will now be enabled. You need to either disable it immediately or change your initial value for the state variable.
You can initialize the draggable and leave it disabled with this (outside the event handler)
('#dragBlock').draggable({disabled: true});
And then you'll only need the .draggable(state) inside the event handler.

Return false not working sometimes

I have a page with photo gallery http://dev.dolina-imeniy.ru/fotogalereya/kp_usadba_tishnevo/
I use this to bind click event and return it false
$('a.link_photo').click(function(e) {
var new_img = $(this).attr('href');
var photo_title = $(this).attr('title');
var photo_info = $('.photo_info', this).html();
$('#photo_view img').attr({
src : new_img
});
$('#photo_title').html(photo_title);
$('#photo_info').html(photo_info);
return false;
});
But on some images it not work! Why it appears?
Try click on 10 image (ut-1-foto.jpg) in my example to see it.
For some reason you code is breaking, so it does not reach to return false.
You can use e.preventDefault(); to stop the default action
e.preventDefault();
The reason for this is that the function only binds to the elements that are already in existent when it is called. Every link created after the the document has loaded will not be bound to this function. To listen for the creation of these elements and to then bind the function to them, you could use the jQuery plugin liveQuery. I hope that helps.
trying calling e.preventDefault()
For more info look here:
http://api.jquery.com/event.preventDefault/
I don't think return false; or event.preventDefault() has anything to do with it. I'm guessing it has to do with how your carousel works. It's no coincidence that your code breaks once the images start repeating - the click event is probably no longer bound. If the element is just being moved, the events should still be set, but if it's being cloned or copied the events might not be.
edit: I can confirm by debugging that your script isn't even called on the 'broken' links.

on Click running twice

http://jsfiddle.net/uTV5k/19/
Hello,
I am using the below script on my mobile site. Please see the jsfiddle of simulated script and markup.
The script below is exactly what's on my mobile site, and the js fiddle is a replicate of it.
In the jsfiddle, the click alternations work fine. The first click opens the animation, and the second click closes the animation.
The problem on my mobile site, the first click opens the animation, and the second animation runs immediately after with-out a second click. But in the fiddle it runs OK.
$(window).load(function(){
$(window).bind("orientationchange resize", function(e) {
$('.home-mod').each(function() {
var homeModule = $(this).height(),
homeTitle = $(this).find('.home-title-button').outerHeight(),
homeStart = homeModule - homeTitle,
homeOpen = false;
$(this).find('.mod-info').css("top", homeStart + "px");
$(this).on('click', function () {
if (homeOpen) {
// second click alternation
$(this).find('.mod-info').animate({ top: homeStart + "px" });
homeOpen = false;
} else {
// first click alternation
$(this).find('.mod-info').animate({ top: 0 });
homeOpen = true;
}
});
});
}).trigger("resize");
});
I'm really not sure why this would be happening. Using this in iScroll shouldnt cause any problems should it?
Thanks in advance
firstly : window load happens
you are calling
.trigger("resize");
which activates the bind on click.
later on - if the window load happens again - it retrigger the code which again - re bind the click
The difference between your fiddle code and your live code is the presence of the resize/orientation handler.
All your other code is inside that meaning that it will get run every time your run your resize handler. http://jsfiddle.net/uTV5k/20/ is a variant of your fiddle with that handler back in. It misbehaves badly.
You can fix this by removing the old click handlers before adding the new ones using .off('click').
This fiddle includes this update and seems to behave again: http://jsfiddle.net/uTV5k/21/
The other (and possibly better) way of fixing this issue is to just recalculate the values you need to in the on resize and store them more globally. Then your click functions can be added once and refer to these global values. This is a much bigger code rewrite and I just went for the very simple fix to highlight your problem.

jQuery: Can't cache onclick handler?

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();
});
});
});

Categories