JavaScript/JQuery event handler problem - javascript

Been playing around a bit with JavaScript/JQuery, and made a "shy" button, instead its just a p-tag with a word. It works ok, except the bool goDown doesn't seem to change, so it always goes down. What's wrong with my code?
Also JavaScript debugging in VS2010 doesn't seem to be working very good, is this a known problem?
Thanks in advance!
if (typeof naarBeneden == 'undefined') {
var goDown = new Boolean(true);
}
$(document).ready(function () {
$(".moveme").animate({ "left": "+=500px"
}, 2000);
$(".moveme").hover(move());
});
function move() {
if (goDown) {
$(".moveme").hover(function () {
$(this).animate({ "top": "+=50px" }, 0)
});
goDown = false;
}
else {
$(".moveme").hover(function () {
$(this).animate({ "top": "-=50px" }, 0)
});
goDown = true;
}
}

The main issue is here:
$(".moveme").hover(move());
You're calling move() not using move as a handler, you need it without the parenthesis, like this:
$(".moveme").hover(move);
Even doing that though, you're assigning a new .hover() handler on each hover event, and I doubt that's really what you're after. It's hard to tell exactly what you're after, but I think this is it:
$(function () {
var goDown = typeof naarBeneden != 'undefined';
$(".moveme").animate({ "left": "+=500px" }, 2000);
.hover(function () {
$(this).animate({ "top": goDown ? "+=50px" : "-=50px" }, 0);
}, function() {
$(this).animate({ "top": !goDown ? "+=50px" : "-=50px" }, 0);
});
});
This assigns an up then down animation if goDown is true when you hover/leave the element, and it does the reverse if goDown is false.

Related

How to call outside function inside animate complete function in Jquery

I have the following code in one of my websites. I have a declared function named "pressedTab(tab)".
When i try to call it inside the following animate complete function, $('#firstShow').animate({'margin-left':'-='+go+'px'}, 1000, 'linear',function() {...pressedTab(tab);} it's not working.
I know its a scope thing but can someone help me fix the code? The strange part is that this code for years it worked. The last year it's not working properly.
<script type="text/javascript">
$(document).ready(function () {
$('.tab1').click(function () {
name('tab1');
});
$('.tab2').click(function () {
name('tab2');
});
$('.tab3').click(function () {
name('tab3');
});
function name(tab) {
function pressedTab(tab) { //FUNCTION THAT I NEED HELP WITH
if (tab == 'tab1') {
$('#img-2 #folder-tab-3').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('#folder-tab-1').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexUp');
$('#folder-tab-2').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('.tab1 p').removeClass('current').addClass('current');
$('.tab2 p').removeClass('current');
$('.tab3 p').removeClass('current');
$('#tug').hide('fast');
$('#tugImages').hide('fast');
$('#vessels').show();
$('#vessels2').hide(0);
} else if (tab == 'tab2') {
$('#img-2 #folder-tab-3').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('#folder-tab-1').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('#folder-tab-2').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexUp');
$('.tab1 p').removeClass('current');
$('.tab2 p').removeClass('current').addClass('current');
$('.tab3 p').removeClass('current');
$('#tug').hide('fast');
$('#tugImages').hide('fast');
$('#vessels').hide(0);
$('#vessels2').show();
} else {
$('#img-2 #folder-tab-3').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexUp');
$('#folder-tab-1').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('#folder-tab-2').removeClass('zindexUp').removeClass('zindexDown').addClass('zindexDown');
$('.tab1 p').removeClass('current');
$('.tab2 p').removeClass('current');
$('.tab3 p').removeClass('current').addClass('current');
$('#tug').show();
$('#tugImages').show();
$('#vessels').hide(0);
$('#vessels2').hide(0);
}
}
if ($('#firstShow').attr('time') == "0") {
var go = "250";
$('#firstShow').animate({
'margin-left': '-=' + go + 'px'
}, 1000, 'linear', function () {
$(this).attr('time', "1");
$('.tab1').attr('time', "1");
$('.tab2').attr('time', "1");
$('.tab3').attr('time', "1");
//Show the right folder
$('#folder-tab-1').show("fast");
$('#folder-tab-2').show("fast");
$('#img-2 > #folder-tab-3').show("fast");
//Hide the Upper of the folder
$('#img-1').hide("fast");
$('#firstShow #folder-tab-3').hide("fast");
//alert(tab);
pressedTab(tab); //FUNCTION WHERE I WOULD LIKE TO BE CALLED BUT IT'S NOT
});
} else {
pressedTab(tab);
}
}
});
</script>
Callback function in animate(...) will be call after name(tab) in context which do not have access to scope of name(tab) function, but it have access to global scope. Try to put pressedTab(tab) outside $(document).ready(...) it should work.

jQuery - firing function on two separate events

I want to make my navigation works in two ways - by clicking arrows and by swiping (on mobiles).
My "click" function is as follows:
$(this).children('.carousel-control').on('click', function() {
config.containers.removeClass('fading');
config.containers.removeClass('fadingback');
if($(this).is('.left')) {
$(this).parent().addClass('fading');
config.mainCont.animate({
scrollLeft: $(this).parent().prev('article').offset().left
}, 500);
} else {
$(this).parent().addClass('fadingback');
config.mainCont.animate({
scrollLeft: $(this).parent().next('article').offset().left
}, 500);
}
return false;
})
Now, I don't know if I can avoid writing it one more time but using swipe instead of on. Is there a way to avoid this?
I tried writing separate functions, like this:
function goLeft() {
$(this).parent().addClass('fading');
config.mainCont.animate({
scrollLeft: $(this).parent().prev('article').offset().left
}, 500);
};
function goRight() {
$(this).parent().addClass('fadingback');
config.mainCont.animate({
scrollLeft: $(this).parent().next('article').offset().left
}, 500);
};
and running them like this:
$(this).children('.carousel-control').on('click', function() {
config.containers.removeClass('fading');
config.containers.removeClass('fadingback');
if($(this).is('.left')) {
goLeft();
} else {
goRight();
}
return false;
})
But it doesn't work.
Any ideas?
I think that the problem is that: you are using $(this) inside your function .try to pass it from your caller
try this:
$(this).children('.carousel-control').on('click', function() {
config.containers.removeClass('fading');
config.containers.removeClass('fadingback');
if($(this).is('.left')) {
goLeft($(this));
} else {
goRight($(this));
}
return false;
})
function goLeft(here) {
$(here).parent().addClass('fading');
config.mainCont.animate({
scrollLeft: $(here).parent().prev('article').offset().left
}, 500);
};
function goRight(here) {
$(here).parent().addClass('fadingback');
config.mainCont.animate({
scrollLeft: $(here).parent().next('article').offset().left
}, 500);
};

Script Lags When Clicking Too Fast [jQuery]

I'm having an issue with a gallery script I wrote. Basically, there's a set of thumbnails and a large image with arrows. When you click on a thumbnail, the current image fades out, and when the new image loads, it fades in. The issue I'm having is that if you click on a thumbnail or arrow a bunch of times during the transition (as if changing the currently displayed image), the entire process starts to get delayed. The more you click, they more you see the delay.
So say I click five times in the middle of the fade transition. After the current transition finishes, if I click on another thumbnail/arrow the scripts effect doesn't start immediately like it's supposed to, it lags for a few seconds and then starts.
Here's my script:
$(".jTscroller a").click(function(event) {
event.preventDefault();
var last = $("#photo").attr("src");
var target = $(this).attr("href");
if (last != target) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
};
});
$("#photo-area .arrow.left").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof prev != "undefined") {
if (prev != current) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",prev);
$("#photo").load(function() {
$("#photo").fadeTo("fast");
});
});
};
};
});
$("#photo-area .arrow.right").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof next != "undefined") {
if (next != current) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",next);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
};
};
});
JS Fiddle: http://jsfiddle.net/G5VAf/7/
My theory for the fix is to add a Boolean variable that gets changed when the animation completes, but the 50 times I've tried it hasn't worked. Hopefully someone more skilled than me can figure it out.
Oh, and I know I should shrink it down to one smaller script, I'm just trying to get this working before going any farther down that road...
Update: Tried implementing the queue thing mentioned below, and now it won't fade in at all.
$("#photo").animate({
opacity: 0
}, {queue: false, duration: 500}, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").animate({
opacity: 1
});
});
});
Update 2: figured it out. Final script:
$(document).ready(function() {
$(".jTscroller a").click(function(event) {
event.preventDefault();
var last = $("#photo").attr("src");
var target = $(this).attr("href");
if (last != target) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
});
$("#photo-area .arrow.left").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof prev != "undefined") {
if (prev != current) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",prev);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
};
});
$("#photo-area .arrow.right").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof next != "undefined") {
if (next != current) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",next);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
};
});
});
Sounds like you are having problems with the animate queue. The jQuery functions you are using are just shorthand for the .animate() function.
.animate( properties, options )
queue: A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string.
Basically each click is then getting added to the animate queue hence the delay. You can try the .animate() function and set queue to false and see if that helps.

jQuery if statement breaks my code

This is my code:
$("#header").touchwipe({
// if($('#cont-wide').css('left') == '-100%' ){
wipeLeft: function() {
$('#cont-wide').animate({
left: '-201%'
}, 500 );
$('#nav-filters').fadeOut(200);
$('#nav-map-l').delay(300).fadeIn(200);
$('#one .col-inner').delay(500).hide(0);
$('#three .col-inner').css('display','block');
setTimeout(function() {
window.scrollTo(0, 1) },
100);
},
wipeRight: function() {
$('#cont-wide').animate({
left: '1%'
}, 500 );
$('#nav-filters').fadeOut(200);
$('#nav-map-r').delay(300).fadeIn(200);
$('#one .col-inner').css('display','block');
setTimeout(function() {
window.scrollTo(0, 1) },
100);
},
min_move_x: 50,
min_move_y: 50,
preventDefaultEvents: false
// }
});
As it currently is it works fine. However when I remove the comments to add the conditional statement, the code and all my other JavaScript stops working. Thanks
You cannot put the if statement there ...
you could do this :
wipeLeft: function() {
if($('#cont-wide').css('left') == '-100%' ){
// the rest
}
},
wipeRight: function() {
if($('#cont-wide').css('left') == '-100%' ){
// the rest
}
}
Note - the css function my not produce the result you are expecting : http://jsfiddle.net/VccAn/ using a value of 10% for left in my example returns auto on Chrome ! See this question / answer for discussions related to this problem : jQuery .css("left") returns "auto" instead of actual value in Chrome
You can't just shove in an if statement in the middle of a statement.
The best solution would be creating your options object before calling touchwipe():
var options = {};
if($('#cont-wide').css('left') == '-100%') {
options.wipeLeft = function() {
};
options.wipeRight = function() {
};
}
$("#header").touchwipe(options);
Note that the if condition is only evaluated once. If you want it to be evaluated on every event, #ManseUK's answer is the way to go.

If statement not working in JavaScript

I've got a minor problem with my jQuery gallery, and I assume it's related to if statement.
You can see how it works here:
http://mojbastovan.com/gallery/lightbox.html
What I want to do is to show description bellow the picture each time I put a mouse over it, however, that doesn't work. Try opening an image and you'll see that when you put your mouse over the bigger image you don't see its description bellow, but when you move the mouse away from image, and put it back over everything works flawlessly.
So what's the problem? I have even added the if statement but it doesn't work, so can anyone help me out with this one?
Oh, and another question, does show, hide and animate functions work choppy for you in Chrome? I've tested it on several browsers, and it seems that Chrome renders those functions bit choppy.
Here's my code:
$(document).ready(function() {
$("#box, #box2, #black, #bgal, #pic, #button").hide();
$("#main img").click(function(){
$("#load").show()
finished=false;
// alert($("#slike").children().size())
broj=$("#main img").index(this)+1;
x=$(this).attr('src');
$.getJSON('baza.json', function(json){
$.each(json.slike, function(i,v){
if (v.t_sr==x){
nsrc=v.sr;
info=v.info;
detail=v.detail;
zamena(nsrc);
//$("#pic img").attr('src',v.sr);
}
if ((broj > 2) && (broj < 9)) {
$("#slike").animate({
left: -152 *(broj-3)
}, 200)
}
else if (broj<3){
$("#slike").animate({
left:0
}, 200)
}
else if (broj>8){
$("#slike").animate({
left: -152 *5
}, 200)
}
});
});
$("#black").show(200, function(){
$("#bgal").show(200);
});
});
$("#slike img").click(function(){
$("#pic").hide(function(){
$("#load").show();
});
// alert($("#slike").children().size())
broj=$("#slike img").index(this)+1;
if ((broj > 2) && (broj < 9)) {
$("#slike").animate({
left: -152 *(broj-3)
}, 200)
}
else if (broj<3){
$("#slike").animate({
left:0
}, 200)
}
else if (broj>8){
$("#slike").animate({
left: -152 *5
}, 200)
}
x=$(this).attr('src');
$.getJSON('baza.json', function(json){
$.each(json.slike, function(i,v){
if (v.t_sr==x){
nsrc=v.sr;
info=v.info;
detail=v.detail;
zamena(nsrc);
//$("#pic img").attr('src',v.sr);
}
});
});
$("#black").show(200, function(){
$("#bgal").show(200);
});
});
$("#pic img").mouseover(function(t){
clearTimeout(t);
$("#info").text(info);
$("#detail").text(detail);
if (finished == false) {
$("#box2").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
$("#box").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
}
});
$("#pic img").mouseout(function(){
t=setTimeout("$('#box2, #box').dequeue().stop(true,true).hide('slide', {direction: 'down'}, 100);",50)
})
$("#button").mouseover(function(){
$("#button img").attr("src","images/button.png");
})
$("#button").mouseout(function(){
$("#button img").attr("src","images/buttono.png");
})
$("#button").click(function(){
$("#bgal").hide(100,function(){
$("#black").hide(100);
$("#pic").hide();
});
});
$("#box2").mouseover(function(){
clearTimeout(t);
})
$("#box2").mouseout(function(){
t=setTimeout("$('#box2, #box').dequeue().stop(true,true).hide('slide', {direction: 'down'}, 100);",50)
});
});
//FUNKCIJE
function zamena(nsrc){
$("#pic").hide();
nimg=new Image;
nimg.src=nsrc; // mora podesena promenljiva iz gl programa
nimg.onload = function(){
$("#load").hide()
$("#pic img").attr('src',nimg.src);
$("#pic").show(1);
$("#button").show();
}
}
$("#pic img").mouseover(function(){
clearTimeout(t);
$("#info").text(info);
$("#detail").text(detail);
if (finished == false) {
$("#box2").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
$("#box").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
}
})
Have you tried adding a t within the function?
$("#pic img").mouseover(function(t){
Also I believe you need to add a semicolon at the end of the function. Try:
$("#pic img").mouseover(function(t){
clearTimeout(t);
$("#info").text(info);
$("#detail").text(detail);
if (finished == false) {
$("#box2").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
$("#box").dequeue().stop(true, true).show('slide', {
direction: 'down'
}, 100);
}
});
I think the issue might be that mouseover event is not being triggered when the image slides under it. There are workarounds (tracking the position of the mouse on the document):
Mouseover/mouseenter not fired by browser on animated/moving element
The animation between my FF and Chrome seemed identical.

Categories