Fade a function out from another function - javascript

I have a function that is fading in and out of four boxes that are in a row and then it loops through again and again. Box 1 fades in and out, then box 2, then box 3, and finally box 4. This is done in one function.
I have another function that when a user hovers over the heading of one of these boxes that box will fade in. Then when they hover off it fades out. What I want to do in that function is when they hover on one of the headings over the box, the function controlling the looping (startSlider) will fade out, then when they hover off the heading the looping begins again.
Here is some code:
function startSlider(){
//code that is looping through each box is here
};
function hoverHere(){
$('.headings .b1').on("mouseenter", function(){
$('.box #1').fadeIn(300);
//startslider() fade out this function
})
.on("mouseleave", function(){
$('.box #1').fadeOut(300);
//startslider() begins again
});
//there is the same code here for .b2 and .box #2 and so on
}
Thanks for any help on how to stop this function from looping when hover is in effect and then to start the startSlider() function when hover is off.

I've put everything in one function so all the variables will be
in scope.. also I'm using .index() which gives you the index of the element
in regards to its parent (a simpler way of connecting between the boxes clicked and the infoboxes affected.
To make the loop start right away, I've separated the actual sliding function from the looping interval, so you can call the function separately in the beginning and then start the loop.. Notice you only need to call startSlider() function in doc ready. Let me know if you have any issues.. If you rather do it the other way and only want the loop function to start immediately than you can just separate the sliding function as in the example.
function startSlider(){
// timer
var loop = 0;
// get total boxes
var count=$('.box .info').length;
// slide index
var sliderIndex = 0;
// boxes
var boxes = $(".headings").children("div");
// info boxes
var infoboxes = $("#main_cont").find(".info");
// bind boxes hover
boxes.off().on('mouseenter', handlehover);
function resetSlider() {
window.clearInterval(loop);
loop=window.setInterval(moveSlider, 2000);
}
function moveSlider() {
if(sliderIndex+1 == count){ //will reset to first image when last image fades out
sliderIndex = 0;
}
infoboxes.fadeOut(400);
infoboxes.eq(sliderIndex).fadeIn(400); // slider image + the next image in the slider
sliderIndex++;
}
function handlehover() {
var boxnum = $(this).index();
boxes.off().on('mouseleave', resetSlider);
pauseSlider();
}
function pauseSlider() {
window.clearInterval(loop);
infoboxes.not(":eq("+boxnum+")").fadeOut(400);
infoboxes.eq(boxnum).fadeIn(400);
}
}
$(function() {
startSlider();
});

Related

Jquery/Javascript Refreshing Click()

I'm creating a simple game where a player creates a 4 color code by clicking on 6 different colored squares, later on the computer player is suppose to be able to guess what the player has selected but that's to happen much later on. Anyway, the problem I'm running into is with click(). I want it so that when you click on each of the squares the result of which square you click on as well as the order is stored in an array, which is to eventually be the player's 4 color code. So far it looks like the information is being stored but not in the way you would expect. If I click on the orange square for instance, that information is stored 4 times so if I print out the array contents it will look like orange, orange, orange, orange. I want it to reset each time a click happens, if that makes any sense. If I click on blue, purple, orange, green and then print out the array it should say blue, purple, orange, green. Any ideas as to what I'm doing wrong? Thanks!
var colorSelection;
var playerCode = [];
$(document).ready(function() {
$('div.codeOption').mouseenter(function() {
$(this).fadeTo("fast", 0.5);
});
$('div.codeOption').mouseleave(function() {
$(this).fadeTo("fast", 1);
});
});
$('div.codeOption').click(function() {
for (i = 0; i < 4; i++) {
colorSelection = $(this).attr('id');
playerCode[i] = colorSelection;
alert(playerCode);
}
});
Working Fiddle Here
you are looping 4 times and setting the same selection each of those 4 times for every click... You were probably thinking you had to loop through each one and figure out which one was clicked, but your jquery click and subsequent $(this) selector takes care of which one was clicked for you, so no need to loop... try this instead
var colorSelection;
var playerCode = [];
var clickCount = 0;
$(document).ready(function(){
$('div.codeOption').mouseenter(function(){
$(this).fadeTo("fast",0.5);
});
$('div.codeOption').mouseleave(function(){
$(this).fadeTo("fast",1);
});
$('div.codeOption').click(function(){
colorSelection = $(this).attr('id');
playerCode [clickCount] = colorSelection;
alert(playerCode);
clickCount++;
});
});
$('div.codeOption').click(function(){
...
colorSelection = $(this).attr('id');
playerCode [i] = colorSelection;
...
});
you are using $(this) in side div.codeOption which will always point to that particular div which has been clicked. Try using something like .each which will do it for all of the divs. Haven't tested it but hope that helps.
$('div.codeOption').click(function(){
$('div.codeOption').each(function(){
//some code
});
});

Animate siblings one by one with delay

Im trying to create animation function where I click on lets say the last child in a list,
then I'll need to move all siblings one by one to the left. So it will go like a wave.
Example:
Click on child nr.4, sibling nr.1 starts to move to the left out of the screen, and with a short delay sibling nr.2 and so on follow after. So it will be like a wave effect.
I have created a JSFiddle: http://jsfiddle.net/10kjn00z/2/
$('#menu li').click(function(){
setVar(this);
$(this).siblings().animate({left: '-'+tWidth+'px'}, function() {
$(this).animate({top: '-'+onSet+'px'});
});
});
This fiddle is just a short snippet off my code, so there might be code thats isnt in use here. But I'll get the idea.
Thanks
You can use the setTimeout() function to achieve what you want.
Here's an example of how you can do it:
$('#menu li').click(function(){
var speed = 100;
setVar(this);
var siblings = $(this).siblings();
$.each( siblings, function(index,value){
setTimeout(function(){$(value).animate({left: '-'+tWidth+'px'});}, index*speed);
});
var current = this;
setTimeout(function(){$(current).animate({top: '-'+onSet+'px'})}, 400-speed+siblings.length*speed);
});
Check it out on jsFiddle
if all the elements to be shifted belong to the same parent:
$('menu li').click(function(event) {
var list = event.currentTarget.parentNode.children;
var i = list.length;
var timeout = 100
while (i--) {
setTimeout(function() {
$(list[i]).animate(/*logic here*/);
}, timeout);
timeout += 100;
}
})
This will iterate through all the children of the parent in reverse order and apply the animation. You can also tweak this to only call on certain siblings. If you want them to iterate in order, use the standard for loop instead of while. The value timeout corresponds to milliseconds of delay and you can adjust the initial and increment values to adjust the animation timing.
You can achieve that behaviour using jQuery.fn.delay, where the delay-time depends on the elements position in the siblings-list.
$('#menu li').click(function(){
setVar(this);
// call .each on siblings, because each will get a different delay
$(this).siblings().each(function(index, sibl) {
$(sibl).delay( index * 250 )
.animate({left: '-'+tWidth+'px'}, function() {
$(this).animate({top: '-'+onSet+'px'});
});
});
});

jQuery making a loop of functions, each with an animate queue

So this is a bit of a head scratcher and I've resorted to asking for help with it. I have created a series of functions with jQuery. Each function contains an animate() queue and ends with a call back that loads the next function, again with it's own animate() queue. Once it reaches the end it calls the first function again and around we go. I have separated the queues into independent functions, because I want to be able to jump to specific points in the loop based on user clicks. So in the code below the loop runs through once, but when it goes back to the beginning the show() and hide() bits don't appear to be doing anything. Any help with this is greatly appreciated!
var firstItem = jQuery('#vehicle-banner-one');
var firstThumb = jQuery('#thumb-one');
var secondItem = jQuery('#vehicle-banner-two');
var secondThumb = jQuery('#thumb-two');
var thirdItem = jQuery('#vehicle-banner-three');
var thirdThumb = jQuery('#thumb-three');
var nextItem = firstItem;
var nextThumb = firstThumb;
firstItem.hide();
secondItem.hide();
thirdItem.hide();
function leadIn(){
console.log('leadIn');
thirdItem.css({zIndex:8});
secondItem.css({zIndex:9});
firstItem.css({zIndex:10});
firstItem.fadeIn("slow", function(){ holdOne(); });
}
function holdOne(){
console.log('holdOne');
thirdItem.css({zIndex:8}).hide();
secondItem.css({zIndex:9}).hide();
firstItem.css({zIndex:10}).show();
firstItem.delay(3000).delay(0, function(){ transTwo(); });
};
function transTwo(){
console.log('transTwo');
thirdItem.css({zIndex:8}).hide();
secondItem.css({zIndex:10}).hide();
firstItem.css({zIndex:9}).show();
secondItem.fadeIn("slow" , function(){ holdTwo(); });
};
function holdTwo(){
console.log('holdTwo');
thirdItem.css({zIndex:8}).hide();
secondItem.css({zIndex:10}).show();
firstItem.css({zIndex:9}).hide();
secondItem.delay(3000).delay(0, function(){ transThree(); });
};
function transThree(){
console.log('transThree');
thirdItem.css({zIndex:10}).hide();
secondItem.css({zIndex:9}).show();
firstItem.css({zIndex:8}).hide();
thirdItem.fadeIn("slow" , function(){ holdThree(); });
};
function holdThree(){
console.log('holdThree');
thirdItem.css({zIndex:10}).show();
secondItem.css({zIndex:9}).hide();
firstItem.css({zIndex:8}).hide();
thirdItem.delay(3000).delay(0, function(){ transOne(); });
};
function transOne(){
console.log('transOne');
thirdItem.css({zIndex:9}).show();
secondItem.css({zIndex:8}).hide();
firstItem.css({zIndex:10}).hide();
firstItem.fadeIn("slow" , function(){ holdOne(); });
};
leadIn();
///toggle by clicking thumbnails
jQuery('#thumb-one').on('click', function(){console.log('1'); holdOne();});
jQuery('#thumb-two').on('click', function(){console.log('2'); holdTwo();});
jQuery('#thumb-three').on('click', function(){console.log('3'); holdThree();});
});
looks kinda complicated... all i understood was, that you are looking for a way to loop through a list of items AND interrupt the loop any time with a click and then start from there on...
i've needed something similar some time before... we start with the snippet from css-tricks.com
All he does, is using the setInterval function to cycle through the elements:
$("#slideshow > div:gt(0)").hide();
setInterval(function() {
$('#slideshow > div:first')
.fadeOut(1000)
.next()
.fadeIn(1000)
.end()
.appendTo('#slideshow');
}, 3000);
this is neat and nice. it shows the first element, fades it out, takes the next element, fades it in and finally appends the first element to the end of the list.
this means, that the visible element is always the first one and therefore good to address.
that was it from css-tricks ... now we are out on our own, and we do want to have a link list, to directly address the single slides... i choose to enumerate all my pages, so this was my solution:
for (i = 1; i <= $("#slides div").length; i++) {
var slideName = $("#slides div").eq(i - 1).attr("name");
$("#slideselect").append("<a href='#' class='singleSelect' name='" + slideName + "'>" + i + " </a>");
}
having a link-list, won't help, as long as you don't have a click function. since the links are inserted after document.ready, i had to use on("click", , function), to have the click handle available...
the function first of all finds the name of the clicked element and compares it to the current active element. in case they match, we won't do anything, since the clicked slide is already shown.
$("#slideselect").on("click", ".singleSelect", function () {
var clickedSlide = $(this).attr("name");
var activeSlide = $('#slides > .activeSlide').attr("name");
clearInterval(cycleHandle);
if (clickedSlide != activeSlide) {
then, because we don't want to destroy our ordered list, we loop through our elements always moving the first one to the last position, until we found our clicked element. afterwards, we fadeout the active slide and fade in the clicked one...
while (clickedSlide != $('#slides > div:first').attr("name")) {
$('#slides > div:first').appendTo('#slides');
}
$('#slides > .activeSlide').fadeOut(1000)
.removeClass("activeSlide").end();
$('#slides > div:first').fadeIn(1000)
.addClass("activeSlide")
.end();
}
cycleHandle = setInterval(function(){myCycle()}, 3000);
});
the code inside my post is already the finished version. what you may notice is the clearInterval and setInterval call... if you won't clear the interval, the clicked slide will correct fade in to display, but the interval keeps running with the old offset. e.g. if you click a page 1 sec before the interval-loop would move on, your clicked slide will be there for only 1sec...
so i took the css-trick snippet into my own cycle function, and call this once after document ready. and inside the click handle, you'll stop the interval and start it again...
well hope you understood my work... here's the fiddle: http://jsfiddle.net/sx1mozeg/2/
there is still strange behaviour with the transitions, if you spam your clicks... need to improve that ...

first time my function runs fine, second time its wrong jquery

I'm trying to make a lightbox. But when i open the lightbox for the second time. It goes trough my code twice. When i open my lightbox the third time, it goes trough my code three times. Don't get it at all.
$(document).ready(function(){
$('.bg-overlay, .overlay-content, .overlay-content img').hide();
$('.thump-bnr > li').click(function(){
// show the overlay and bg-overlay
$('.bg-overlay, .overlay-content').fadeIn(500);
// gets the index of the thunp thats been clicked in the banner
var x = $(this).index();
// console.log(x);
$('.overlay-content > img').eq(x).fadeIn(500);
// thumpPop checks if there aren't to mutch list items
var thumpPop = $('.overlay-content .thump-pop li').length;
// console.log(thumpPop);
// appends all li for the thump navigation in the overlay
if (thumpPop < 1) {
$('.overlay-content').append('<ul class="thump-pop"></ul>');
for (var i = 0; i < 4; i++) {
$('.thump-pop').append('<li></li>');
}
}
// sets all thump li to the border white
$('.thump-pop > li').css("border-color", "#fff");
// sets the active thump li to a dark border
$('.thump-pop > li').eq(x).css("border-color", "#e2e2e2");
// console.log(x);
// calls the thumpNav function for the thump navigation
thumpNav();
// calles the arrowNav function for the arrow navigation beside the big images
arrowNav();
});
In this function i have managed to execute the function only once by using an if statement.
// this is the function for the thump navigation
function thumpNav() {
$('.thump-pop > li').click(function(){
// get the index number of the thump li
var y = $(this).index();
// console.log(y);
// checks if the big image thats equal to the clicked thump is hidden
if($('.overlay-content > img').eq(y).is(':hidden')) {
// fadeIn and fadeOut the big images
$('.overlay-content img').fadeOut();
$('.overlay-content > img').eq(y).fadeIn();
// this wil change the border color of the active li
$('.thump-pop > li').css("border-color", "#fff");
$(this).css("border-color", "#e2e2e2");
}
});
}
I think i have made a mistake in the function arrowNav(), because he executes this twice when i open my lightbox for the second time.
function arrowNav() {
$('.arrow-nav-left').click(function(){
// this wil get the index number of the visible image in the overlay. This number can be used to display the number -1 our +1
var x = $('.overlay-content').find('img:visible').index();
// console.log(x);
var x = x - 2;
console.log(x);
$('.overlay-content > img').hide();
$('.overlay-content > img').eq(x).show();
});
}
// hides the pop-up
$('.bg-overlay').click(function(){
$('.bg-overlay, .overlay-content, .overlay-content img').fadeOut(500);
});
});
Please help me, and some feedback on the code is alway helpfull. Thanks
The problem is here:
function thumpNav() {
$('.thump-pop > li').click(function(){
You're attaching a new click handler everytime you call thumpNav, and they will all execute and do the same thing everytime you click.
Replace with:
function thumpNav() {
$('.thump-pop > li').unbind("click").click(function(){
Just like you did with arrowNav().
Note that your code is very unefficient and not structured quite right. Even if this works it's not good when you're juggling click handlers like this. At least define the callback as a seperate function and pass that as an argument to click().
If you want to get help with improving your code, you can always post it on Codereview.
Every time you're calling:
thumpNav();
you're attaching a new click handler.
same with arrowNav()
but atleast here you unbind first.

fade in a series of divs then fade out the previous one

So using jquery, I got a bit of javascript to fade in a series of divs over a certain amount of time. Now I want to fade out the previous div. Would I be right in putting a fade out function as a call back in the fade in function?
So it would look like this.
<script type="text/javascript">
$(function() {
$("div").each(function(i, e) {
$(this).delay(i*400).fadeIn(
$(this).delay(i*400).fadeOut);
});
});
</script>
Would that be right or am I doing it wrong?
You have a few syntax problems, the callback should be like so:
$("div").each(function(i, e) {
$(this).delay(i*400).fadeIn(function() {
$(this).delay(i*400).fadeOut();
});
});
Demo: http://jsfiddle.net/tymeJV/FJMa4/
Try this, if you need to cycle through and fixed syntax.
Demo
var arrDivs = $("div").get(); //Get all the divs into an array
function fade()
{
var div = arrDivs.shift(); //get the top div
var $this = $(div);
arrDivs.push(div); //push it to the end for cycle to repeat
$this.delay($this.index()*400).fadeIn(function(){ //get the index to calculate the delay time.
$this.delay($this.index()*400).fadeOut(function(){
window.setTimeout(fade,1000);
});
});
}
fade();

Categories

Resources