edit
my code is now at the end of the document and it works. thx for help.
question
I want to call a click function...but when i click on my link the site reloads.
Here is my code:
(function(window, undefined) {
var gn = (function(){
var sitelength = $(window).width(),
$next = $('.next'),
$start = $('.start'),
init = function(){
_scrollto();
_checkmenu();
},
_scrollto = function(){
$next.on( 'click', function( event ) {
$('html,body').animate({scrollLeft: $("body").offset().left+200},1500);
return false;
});
$start.on( 'click', function( event ) {
$('html,body').animate({scrollLeft: $("body").offset().left+0},1500);
return false;
});
},
_checkmenu = function(){
$(window).scroll(function(e){
if($(this).scrollLeft()>100 && (!$('#side').hasClass('ac'))){
$('#side').addClass('ac');
$('#side').animate({ left : -230 }, 'slow');
$('#sitenav').animate({ left : 0 }, 'slow');
}
if($(this).scrollLeft()<100 && $('#side').hasClass('ac')){
$('#side').removeClass('ac');
$('#side').animate({ left : 20 }, 'slow');
$('#sitenav').animate({ left : -50 }, 'slow');
}
});
}
return { init : init };
})();
gn.init();
})(window);
but when i exclude the whole click thing in a "$(document).ready(function())" it works fine.
$(document).ready(function(){
var $next = $('.next'),
$start = $('.start');
$next.on( 'click', function( event ) {
$('html,body').animate({scrollLeft: $("body").offset().left+200},1500);
return false;
});
$start.on( 'click', function( event ) {
$('html,body').animate({scrollLeft: $("body").offset().left+0},1500);
return false;
});
});
can someone tell me why and how to fix it?
The $.ready() function doesn't execute until the DOM is 'ready', meaning the browser has had time to download and parse the rest of your page.
Assuming your code is in the <head> tag, in your first example the code will be executed as soon as the browser encounters it. The browser tries to bind the click event to $('.next'), but the element hasn't been created yet, so the event never gets bound.
Wrapping code like this is $.ready() is very good practice, so your second example is a much better solution.
When you do not wrap your code in $(function () {...});, the DOM is not yet fully loaded, when your code is executed and therefore $('.next') and $('.start') actually apply to no elements.
This happens because today's JS engines are so fast and optimized that they could execute your whole script, before the browser has fully loaded the page.
Related
Edit: I guess part of this is an issue of me being inexperienced with Drupal. I added a javascript file to site.info, so that it will be added to every page. This is all the file contains:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
When the site loads, it gets compiled into this larger script, which looks like this in the debugger:
(function ($) {
Drupal.behaviors.titlebar = {
init: function(context, settings) {
// Using percentage font size to easily increase/decrease page font size
var baseFontSize = 100;
$('.pgc-font-size a').click(function() {
if($(this).hasClass('increase')) {
if(baseFontSize < 150)
baseFontSize += 20;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
} else {
if(baseFontSize > 70)
baseFontSize -= 10;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
}
});
// Print button
$('.pgc-print a').click(function() {
window.print();
})
}
};
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.titlebar.init();
});;
(function ($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function(){
if($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
;
You can see my little script at the bottom there. It says there's something wrong with the first line, but I'm not sure what the problem is. What change would I need to make to my javascript file to make sure it compiles right?
I'm probably overlooking a really simple type, but I can't see what's wrong with my jQuery.
This is the part that's not working:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.website.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
I have jQuery on my site, I know I do because this it's used earlier in the code with no problem. The error is showing in the debugger on the first line, '$("#ct100_btnSearch001").on("click", function(){ '. Here is a larger section of the script page:
(function($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function() {
if ($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function($) {
$("#ctl00_btnSearch001").on("click", function() {
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);;
Try to install jQuery update Module.
If you are using Drupal 6, you are not be able to use on function.
One option is to include your custom version of jQuery in your page.tpl.php, another option (not recommended) is to use live, but now is deprecated.
You can bind a function to an event use two way:
1.use bind() method and the event name as the first argument
$( "#foo" ).bind( "click", function() {
alert( "User clicked on 'foo.'" );
});
or
2.just use the event method
$( "#foo" ).click( function() {
alert( "User clicked on 'foo.'" );
});
The problem of your code is that there isn't a on event.
ref http://api.jquery.com/category/events/mouse-events/
If ctl00_btnSearch001 is a correct id for what ever you are trying to click. Try changing it to this:
(function ($){
$(document).on("click", "#ctl00_btnSearch001", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
I have a panel that slides open on an element click called "details" and populates the panel via ajax depending on the data attribute value. I also have it setup that if you close outside that panel, it will close. If the panel is open and the user clicks on a different "details" element, I want the panel to close and open again populated with the data from the new data attribute.
Problem is that the codes checks if the panel is visible and won't load the ajax if it is. How can I change this so the click event knows the mousedown event is completed before it does it's thing?
// SLIDING PANEL
$(".details").on("click", function(e){
e.preventDefault();
var panel = $("#DetailsPanel");
var mkey = $(this).data("masterkey-id");
var _self = $(this);
// fetch data ONLY when panel is hidden...
// otherwise it fetches data when the panel is closing
if (!panel.is(':visible')) {
panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
// if the ajax source wasn't loaded properly
if (status !== "success") {
var msg = "<p>Sorry, but there was an error loading the document.</p>";
panel.html(msg);
};
// this is part of the .load() callback so it fills the panel BEFORE opening it
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().addClass("warning");
});
});
} else {
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().removeClass("warning");
});
};
return false;
});
$(document).on("mousedown", function(){
$("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
//_self.parent().parent().removeClass("warning");
});
});
// don't close panel when clicking inside it
$(document).on("mousedown","#DetailsPanel",function(e){e.stopPropagation();});
$(document).on("click", "#ClosePanel", function(){
$("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
$("#LeadsTable tr").removeClass("warning");
});
});
// END SLIDING PANEL
Setting a timeout worked for me in another context:
onclick="window.setTimeout( function(){ DO YOUR STUFF }, 2);"
This solves many problems of this type.
I'm not totally sure about this but if you use "mouseup" instead "click" could work as you expect. Try it and let me know if I'm wrong.
Ok, so I found this little nugget http://www.gmarwaha.com/blog/2009/06/09/jquery-waiting-for-multiple-animations-to-complete/ and it works pretty good. No issues so far.
Here is the new code
$(".details").on("click", function(e){
e.preventDefault();
var panel = $("#DetailsPanel");
var mkey = $(this).data("masterkey-id");
var _self = $(this);
// fetch data ONLY when panel is hidden...
// otherwise it fetches data when the panel is closing
var wait = setInterval(function() {
if( !$("#DetailsPanel").is(":animated") ) {
clearInterval(wait);
// This piece of code will be executed
// after DetailsPanel is complete.
if (!panel.is(':visible')) {
panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
// if the ajax source wasn't loaded properly
if (status !== "success") {
var msg = "<p>Sorry, but there was an error loading the document.</p>";
panel.html(msg);
};
// this is part of the .load() callback so it fills the panel BEFORE opening it
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().addClass("warning");
});
});
} else {
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().removeClass("warning");
});
};
}
}, 200);
return false;
});
I want to prevent clicking on an element, while it performs some animations and then enable it later. I have tried to use unbind and then bind, but clicking remains permanently disabled.
Is there any other way to do it?
$("something").on("click", function() {
$("selected").unbind("click");
$("selected").animate({...}, function() {
$("selected").unbind("click");
});
basically, i don't want someone to click on the selected div while the animation is in progress, as clicking on it will start another set of animations which i don't want to start in between.
Try this, using a flag variable to store the info if the animation is happening:
var animating = false;
$("something").on("click", function () {
animating = true;
$("selected").animate({...
}, 1000, function () {
animating = false;
});
});
$("selected").click(function(){
if (animating) return false;
});
Use on and off this way you can "bind" the function foo to a click event on a particular element, switch it off and on again, as many times as you like. Have fun ;-)
DEMO: http://jsfiddle.net/4yBbb/2/
var foo = function() {
// Code to handle some kind of event
};
// ... Now foo will be called when paragraphs are clicked ...
$( "p" ).on( "click", foo );
// ... Foo will no longer be called.
$( "p" ).off( "click", foo );
edit: updated answer, my example used delegation and this was not necessary.
applied to your example it would look like this:
$("something").on("click", function() {
$("selected").off( "click", foo );
$("selected").animate({...}, function() {
$("selected").on( "click", foo );
});
clicking remains permanently disabled.
Because when never bind the "click" again to $("something"). Try:
$("something").on("click", function animate() {
var _this = $(this);
_this.off("click");
$("selected").animate({...}, function() {
_this.on("click",animate);
});
Here I use named function to make it easy to refer to the function again.
How about adding a check in your click function to perform the animation only when the clicked element is not animating?
$("something").on("click", function() {
$("selected").animate({...});
});
$("selected").on("click",function(){
if(!$(this).is("selected:animated")){
//Start other animation
}
});
Demo fiddle
Use .on() & .off() event of jquery. here is the example Jquery API
you need to do somthing like as follows:
function flash() {
// do your stuff here
}
$("something").on("click", function() {
$( "body" ).off( "click", "Your Div Selector", flash );
});
$("something").on("click", function() {
$( "body" ).on( "click", "Your Div Selector", flash );
});
I have a function that uses ajax to load content throughout one of my sites.
This works all good but at some parts because new content is brought in that has more links I need to make the click function a live click function, but when I do the ajax stops working and it just changes the page as normal ( without ajax )
here is my code
function ajaxLoads(){
var $btn = $('a.ajax-btn');
var $container = $('#load');
var siteTitle = document.title;
//var $artistBG = $('#artist-viewport img');
$btn.click(function(e){
console.log();
e.preventDefault();
$btn.removeClass('selected');
//$artistBG.removeClass('top');
var sourceTarget = $(this).data('page'),
slideWidth = $container.width(),
$this = $(this),
$background = $this.data('background'),
pageUrl=$this.attr('href'),
pageTitle = $this.html();
//$changeTo = $("#artist-viewport img[data-background='"+ $background +"']");
$this.addClass('selected');
//$changeTo.addClass('top');
$container.animate({'right':-slideWidth}, 300, 'easeInExpo');
$container.load(pageUrl+" "+sourceTarget, function(){
subNav();
$("html, body").animate({ scrollTop: 0 }, 500, 'easeInExpo', function(){
$container.animate({'right':0}, 300, 'easeInExpo');
});
var pageContent = $(this).html();
window.history.pushState({"html":pageContent, "pageTitle": pageTitle},"", pageUrl);
//document.title=pageTitle+" :: "+siteTitle;
}); // end load function
}); // end click function
window.onpopstate = function(e){
if(e.state){
$container.css('opacity', 0).html(e.state.html).fadeTo('fast', 1);
document.title=e.state.pageTitle+" :: "+siteTitle;
}
};
}
I have tried changing the $btn.click(function(e) to $btn.live('click', function(e) and to $btn.on('click', function(e)
Add .on on document.
$(document).on('click','a.ajax-btn',function(){ });
try on
$('#load').on('click', '.ajax-btn', function(){
...
});
live is deprecated in jquery 1.8 and removed in 1.9.. so use on()
Give your button a css class and use this
$(document).on("click",".yourcssclass",function(e){});
This will work since by default, most events bubble up from the original event target to the document element.Though this degrades performance, a click event happens infrequently and you might use this as a fix to your problem.Then when you have time ,try to see why using delegates is not working by carefully looking on your page cycle.
So, i have some animation actions, this is for my login panel box:
$('.top_menu_login_button').live('click', function(){
$('#login_box').animate({"margin-top": "+=320px"}, "slow");
});
$('.login_pin').live('click', function(){
$('#login_box').animate({"margin-top": "-=320px"}, "slow");
});
now i need to add some hiding action after click on body so i do this:
var mouse_is_inside = false;
$('#login_box').hover(function () {
mouse_is_inside = true;
}, function () {
mouse_is_inside = false;
});
for stop hiding this element on body click, and this for body click outside by login-box
$("body").mouseup(function () {
if (!mouse_is_inside) {
var login_box = $('#login_box');
if (login_box.css('margin-top','0')){
login_box.stop().animate({"margin-top": "-=320px"}, "slow");
}
}
});
Everything is fine but this panel animates after each body click, how to stop this and execute only one time? Depend on this panel is visible or not?
You'd normally do this sort of thing by checking if the click occured inside the element or not, not by using mousemove events to set globals :
$(document).on('click', function(e) {
if ( !$(e.target).closest('#login_box').length ) { //not inside
var login_box = $('#login_box');
if ( parseInt(login_box.css('margin-top'),10) === 0){
login_box.stop(true, true).animate({"margin-top": "-=320px"}, "slow");
}
}
});
And live() is deprecated, you should be using on().