glitchy jquery div carousel - javascript

so i've made a jquery carousel which you can see here: http://teste.boleiafacil.com/ (it's the one in the end of the page
this is the jquery:
//highlights slide animation
var prdlength = $(".rproducts").length;
var prdleft = 1;
var i = 0;
function swapC() {
i++;
prdleft++;
$(".rproducts").each(function(){
$(this).animate({"left":"-" + prdleft + "px"}, 10);
if (prdleft == 180){
$(this).appendTo(".rproductswrapper");
prdleft = 0;
}
});
if (i == prdlength) {
i = 0
}
window.setTimeout(function() { swapC() }, 10);
}
$(window).on("load", swapC);
the problem is when the divs get appended to the end of the wrapper it looks glitchy.
how can i fix this?

Try wrapping your function in a document ready rather than window load, the shorthand for it is:
$(function(){
//code here
});

Related

JS - How to run something when a function has ended

Here is a code that should open and close my site's menu. The menu is divided to divs and each one is timed to enter the screen after the other.
<script type="text/javascript">
var s=0;
function menuOpen() {
if (s==0){
document.getElementById("menu_icon").src = "x.png";
document.getElementById("nav_menu").style.zIndex = "3";
$('.box-wrapper').each(function(index, element) {
setTimeout(function(){
element.classList.remove('loading');
}, index * 100);
});
s++;
} else {
document.getElementById("menu_icon").src = "menu_icon.png";
$('.box-wrapper').each(function(index, element) {
setTimeout(function(){
element.classList.add('loading');
}, index * 100);
});
s=0;
// how to make this part run after the menu has finished folding?
setTimeout(function(){
document.getElementById("nav_menu").style.zIndex = "1";
}, 1500);
}
}
</script>
The content of the page is at z-index 2. The menu when folded is at 1 and when open at 3.
Is there a way to run the command moving the menu to z-index 1 after the menu has finished folding completely?
Currently what I did was to time the animation (1600ms) and use setTimeout. But this timing will change if I'll add more lines to my menu or if someone is clicking rapidly on the menu icon.
I'm rather new to JS and Jquery so go easy on me (:
Thanks of your help.
Below you can find the code and link to jsfiddle. Unfortunetly jsfiddle blocks the animate method for unknown reason so I don't debug, but even if it code will not work :))) I hope you will cathch the idea. And also some explanation.
Firstly our items are hidden. There are two functions displayMenu and hideMenu, they are similar, but display - run animations from the top invisible, and hide - start hide items from the bottom visible. To prevent mess I use two flags and two classes, first openFlag it is say what animations should be played now. Our hide and display functions are recursive and after they end current animation(hide or show) they check openFlag, and play next hide/show or start another chain of hide/show functions. It is the most difficult to understand part) But important that with it you can click as many times as you want and all would be fine and would be never broken by clicks.
Two classes we use as animation-chain can change behaviour and we need the way to choose items that alredy visible or hidden, so this why after each animation we set only one of this classes and remove another.
Now there is one problem if all animation are ended when we click button we should start new chain of animations, but if chain has been already started we need just to switch openFlag, and when current animation stops, it will change the behaviour. So this is the reason for btnFlag it is 1 if no active chain-animations at this moment.
After the last execution of element of animation-chain it will call callback arg, that you should pass, also at this moment will set btnFlag to 0, that means that animation-chain stopped. The openFlag as you remember changed at moment og click.
function end() {
console.log("here you can set zIndex");
}
var openFlag = 0; //become 1 after we start open elems
var btnFlag = 1;
$(document).ready(function() {
$('.toggleMenu').click(function() {
if (!$('.menuBlocks').hasClass('visible')) {
if (openFlag == 0) {
openFlag = 1;
if (btnFlag) {
var items = $('.invisibleItem');
var amount = items.length;
displayMenu(0, amount, items, end);
}
}
} else {
openFlag = 0;
if (btnFlag) {
var items = $('.visibleItem');
var amount = items.length;
hideMenu(amount - 1, items, end);
}
}
});
});
function displayMenu(i, amount, items, callback) {
if (i < amount && openFlag) {
items[i].animate({
"width": "100px"
}, 1000, function() {
items[i].removeClass('invisibleItem');
items[i].addClass('visibleItem');
displayMenu(i + 1, amount, items);
});
} else if (!openFlag) {
var items = $('.visibleItem');
var amount = items.length;
hideMenu(amount - 1, items, makeToggleVisible);
} else {
btnFlag = 1; //all aniimations ended
callback();
}
}
function hideMenu(i, items, callback) {
if (i < 0 && openFlag) {
items[i].animate({
"width": "0px"
}, 1000, function() {
items[i].removeClass('visibleItem');
items[i].addClass('invisibleItem');
hideMenu(i - 1, amount, items);
});
} else if (!openFlag) {
var items = $('.invisibleItem');
var amount = items.length;
displayMenu(0, amount, items, makeToggleVisible);
} else {
btnFlag = 1; //all animations are ended
callback();
}
}
https://jsfiddle.net/ShinShil/nrtyshv5/4/
Ok fixed it.
I moved everything to jquery. Used animate and promise.
This is what came out at the end. It is a side menu that will open it's li elements one-by-one.
var s=0;
var navMenu = document.getElementById("nav_menu");
var navBtn = document.getElementById("btn");
$(document).ready(function(){
$("button").click(function(){
if (s==0) {
navMenu.style.zIndex = "4";
navBtn.classList.add('close');
$('ul').each(function() {
$(this).children().each(function(i) {
$(this).delay(i * 100).animate({left:0});
});
});
$( "li" ).promise().done(function() {
navMenu.style.zIndex = "4";
});
s++;
}
else {
navBtn.classList.remove('close');
$('ul').each(function() {
$(this).children().each(function(i) {
$(this).delay(i * 100).animate({left:"100%"});
});
});
s=0;
$( "li" ).promise().done(function() {
navMenu.style.zIndex = "1";
});
}
});
});
and with CSS transitions.
var s=0;
function menuOpen() {
if (s==0){
document.getElementById("menu_icon").src = "x.png";
document.getElementById("nav_menu").style.zIndex = "3";
$('.box-wrapper').each(function(index, element) {
setTimeout(function(){
element.classList.remove('loading');
}, index * 100);
});
s++;
$("#last").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
document.getElementById("nav_menu").style.zIndex = "3";
});
} else {
document.getElementById("menu_icon").src = "menu_icon.png";
$('.box-wrapper').each(function(index, element) {
setTimeout(function(){
element.classList.add('loading');
}, index * 100);
});
s=0;
$("#last").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
document.getElementById("nav_menu").style.zIndex = "1";
$("#nav_menu").scrollTop(0);
});
}
}

Continuously fade in and out

I have this JavaScript to make the div flash every two seconds. I was wondering if I could add anything into this current function so that the div fades in and out instead of appearing and disappearing with no transition.
JavaScript
<script language = "javascript">
function flash()
{
var blinker = 2000
var timeIn = setInterval(function() {
var element = document.getElementById('sign');
element.style.visibility = (element.style.visibility == 'hidden' ? '' : 'hidden');
}, blinker);
}
</script>
HTML div
<div class = "sign" id = "sign">
<p> hello </p>
</div>
Since you've tagged jQuery, you can simplify it to:
$('#sign').fadeIn(2000); // fade-in in 2 seconds
and
$('#sign').fadeOut(2000); // fade-out in 2 seconds
or as pointed out by user: Bondye
function flash() {
$('#sign').fadeToggle(2000);
}
If you want it to continue fading in and out.. you could try something like this:
function keepFading($obj) {
$obj.fadeToggle(2000, function () {
keepFading($obj)
});
}
keepFading($("#sign"));
See working example in Fiddle
This function would then work on any jquery object you pass it. So if you have something else you want to do the same thing you can just call it like keepFading($("#someOtherEle"));
For this to work, you'll need to make sure that jquery is included. You can then put the above code at the bottom of your html... or in your head if you wrap in a $(document).ready( ... )
You can implement fadeIn and fadeOut on pure javascript:
function fadeOut(id,val){
if(isNaN(val)){
val = 9;
}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val–;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{
return;
}
}
function fadeIn(id,val){
// ID of the element to fade, Fade value[min value is 0]
if(isNaN(val)){
val = 0;
}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{
return;
}
}
Here's a FIDDLE
setInterval(function() {
$('.sign').animate({ opacity: '0' }, 800).animate({ opacity: '1' }, 800);
}, 2000);
It is also possible to fadeToggle with jQuery. See details here:
http://api.jquery.com/fadeToggle/
<script>
function flash(id) {
$('#'+id).fadeToggle();
}
var blinker = 2000;
var timeIn = setInterval(function() {
flash('sign');
}, blinker);
</script>

div with an id wont accept any event handlers JavaScript. No Jquery

Im trying to pause a timed slideshow when you're hovering over a div
<div id="play_slide" onMouseOver="clearTimeout(playTime)"></div>
If i put onMouseOver="clearTimeout(playTime)" inside an li on the page, it'll pause, so I know my code is correct, it just wont work on the div! Also if i get rid of the id, it will alert when i put an alert function into an event handler
This is the js.
var playTime;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
you can see this here: www.nicktaylordesigns.com/work.html
I would do it like this:
( and no inline script... just <div id="play_slide">Something</div> )
var playTime;
var indexPlay = 0;
var slideElement;
window.onload = function () {
slideElement = document.getElementById("play_slide");
slideElement.addEventListener('mouseenter', function () {
console.log('stop');
clearTimeout(playTime);
});
slideElement.addEventListener('mouseleave', function () {
console.log('continue');
playTime = setTimeout(playSlide, 2500);
});
playSlide();
}
function playSlide() {
var slideshow = slideElement.style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if (indexPlay > images.length - 1) {
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/" + images[indexPlay] + ".png')";
playTime = setTimeout(playSlide, 2500);
}
Fiddle
This issue is related to the script loading. Your script gets loaded after the DOM is processed so function doesn't get attached to the event.
If you are using jQuery then you can use below code.
$(function () {
$("#play_slide").mouseover(function(){
var playTime = 33;
clearTimeout(playTime);
});
});
If you don't want to use JQuery then you can do the same thing in JavaScript as below.
window.onload = function(){
document.getElementById("play_slide").onmouseover = function(){
var playTime = 33;
clearTimeout(playTime);
};
}
I got it! the div tag was somehow broken, I coded a div around it and gave it the event handlers and a class. That worked, then i simply changed the class to an id and got rid of the original div. Idk what was going on but it works now. Thanks for your suggestions!
Can you try this,
<div id="play_slide" onmouseover="StopSlide();">Stop</div>
<script>
var playTime;
var indexPlay;
function playSlide()
{
var slideshow = document.getElementById("play_slide").style;
var images = new Array("an", "complete", "red", "thirteen");
indexPlay++;
if(indexPlay > images.length - 1)
{
indexPlay = 0;
}
slideshow.backgroundImage = "url('assets/images/play/"+images[indexPlay]+".png')";
playTime = setTimeout("playSlide()", 2500);
}
function StopSlide(){
window.clearTimeout(playTime);
}
playSlide();
</script>

How to toggle an animation upon clicking a button

I have the following j-query code (using the jquery plugin ajax/libs/jquery/1.10.1) to move a div element to the left upon clicking on a separate div element:
<script>
$(document).ready(function(){
$("#tab_box3").click(function(){
$.fx.speeds._default = 800;
$("#tab3").animate({left:"+=97%"});
});
});
</script>
What I want to happen is when the #tab_box3 div is clicked on a second time, the #tab3 div moves back to where it originally started.
I tried the following, using Toggle, but it does not seem to have worked:
<script>
$(document).ready(function(){
$("#tab_box3").click(function(){
$.fx.speeds._default = 800;
$("#tab3").animateToggle({left:"+=97%"});
});
});
</script>
Can anyone offer advice please?
You must doing something like this :
$(document).ready(function(){
$("#tab_box3").click(function(e){
var element = $(this),
clicked = parseInt(element.data('clicked')) || 0;
element.data('clicked', clicked + 1);
$("#tab3").stop();
if (clicked % 2 == 0)
{
$("#tab3").animate({left:"+=97%"}, 800);
}
else
{
$("#tab3").animate({left:"-=97%"}, 800);
}
e.preventDefault();
});
});
An example here :
http://jsfiddle.net/Q5HDu/
You will have to use -=97% to offset the previous animation change.
var $tab3 = $("#tab3");
if ($tab3.data("animated")) {
$tab3.animate({left: "-=97%").data("animated", false);
}
else {
$tab3.animate({left: "+=97%").data("animated", true);
}

jQuery fade image loop

I want to make a loop in my function so that the slideshow effect always restarts.
Here's my fiddle : http://jsfiddle.net/Be67B/
It's all good for the image 1 to go to image 2, but I want it to fade it back to the image 1, and then go the image 2, and so on...to always loop like that.
What do I need to add in my code to make this work?
Don't use a loop, just ask the browser to repetitively call your animation step :
setInterval(function(){
// your animation (in fact just a step)
}, someDelay);
Demonstration : http://jsfiddle.net/dystroy/nPh6S/
In this precise case, the animation is done with :
setInterval(function(){
$("#top").fadeOut(function() {
$(this).attr("src","http://1.bp.blogspot.com/-cFt5KNrHsHc/TZMH6XUBu-I/AAAAAAAAAR4/R6hOP7lffx0/s1600/apple-logo.png").fadeIn().delay(1000).fadeOut(function(){
$(this).attr('src', 'http://coreldrawtips.com/images/applebig.jpg').fadeIn().delay(1000);
});
}
);
}, 4000);
see this jquery cycle plugin:
http://jquery.malsup.com/cycle/
may be this is what you want
You can create a function that does the transition, which has a callback function as part of the fadeIn method that will call back to itself to trigger the next transition, and it would just be in a constant loop.
Here's your modified jsfiddle:
http://jsfiddle.net/Be67B/1/
HTML:
<img id="top" src="http://coreldrawtips.com/images/applebig.jpg" width="300" height="300" />​
Javascript:
$(document).ready(function(){
transition(false);
});
function transition(first)
{
var src = first ? "http://coreldrawtips.com/images/applebig.jpg" : "http://1.bp.blogspot.com/-cFt5KNrHsHc/TZMH6XUBu-I/AAAAAAAAAR4/R6hOP7lffx0/s1600/apple-logo.png";
$("#top").delay(1000).fadeOut(function() {
$(this).attr("src",src).fadeIn(function() {
transition(!first);
});
});
}
​
I just made this code:
$(document).ready(function(){
// images in the pool
var images=["http://1.bp.blogspot.com/-cFt5KNrHsHc/TZMH6XUBu- I/AAAAAAAAAR4/R6hOP7lffx0/s1600/apple-logo.png",
"http://1.bp.blogspot.com/-cFt5KNrHsHc/TZMH6XUBu-I/AAAAAAAAAR4/R6hOP7lffx0/s1600/apple-logo.png"];
// next image to display
var next = 0;
// interval beetween images
var INTERVAL = 1000;
// main function
var doCarrousel = function() {
$("#top").fadeOut(function() {
$(this).attr("src", images[next]).fadeIn(
function() {
setTimeout(doCarrousel, INTERVAL);
});
});
if (++next >= images.length)
next = 0;
};
//start carrousel
doCarrousel();
});
fiddler: http://jsfiddle.net/Be67B/
I would use a plugin. But you can do it by hand. I just recommend against changing the src of the images, because some browsers don't handle it very well, like safari not firing load event.
Instead, have all images inside a container, and cycle their visibility:
$(document).ready(function(){
var currentImage = $("#images img:first");
setInterval(function(){
currentImage.fadeOut();
if(currentImage.next().size())
currentImage = currentImage.next();
else
currentImage = currentImage.siblings().first();
currentImage.fadeIn();
}, 1000)
});
See fiddle: http://jsfiddle.net/Be67B/2/
Quick and dirty: jsFiddle example
function swap(img) {
img = (img == 'http://coreldrawtips.com/images/applebig.jpg') ? 'http://1.bp.blogspot.com/-cFt5KNrHsHc/TZMH6XUBu-I/AAAAAAAAAR4/R6hOP7lffx0/s1600/apple-logo.png' : 'http://coreldrawtips.com/images/applebig.jpg';
$('#top').delay(2000).fadeOut(function() {
$(this).attr('src', img)
}).fadeIn(function() {
setTimeout(function() {
swap(img)
}, 1000);
});
};
swap($('#top').attr('src'));​

Categories

Resources