Firefox setTimeout + jQuery fade loop inconsistent, stops early, won't cycle - javascript

http://jsfiddle.net/x6PCD/11/
I'm trying to make a slideshow that fades between several absolute-positioned div's. On Chrome, IE9, Opera the code below works fine. But on Firefox, the timeout goes once or twice, then stops. If you remove the JS section marked below, it loops properly.
<style>
.slide {position:absolute; top:0; left:0; width:300px; height:200px}
</style>
<div id="slides" class="slides">
<div class="slide slide1" style="background:#c66">
<div class="swap_links">
1
2
3
</div>
</div>
<div class="slide slide2" style="background:#6c6">
<div class="swap_links">
1
2
3
</div>
</div>
<div class="slide slide3" style="background:#36c">
<div class="swap_links">
1
2
3
</div>
</div>
</div>
<script type="text/javascript">
$(function() {
var fp = '#slides .slide';
var fs = 300;
var t = window.setTimeout(swap, 1000);
$(fp).slice(1).hide();
function swap(to) {
//removing this section, loop plays in FF
if (to) {
$(fp + to).fadeIn(fs);
$(fp).not('.slide' + to).fadeOut(fs);
window.clearTimeout(t);
return;
}
$(fp).eq(1).fadeIn(fs);
$(fp).eq(0).fadeOut(fs, function() {
$(this).appendTo('#slides');
t = window.setTimeout(swap, 1000);
});
}
$('#slides .swap_links a').click(function() {
swap($(this).html());
});
});
</script>

FireFox appears to have been passing arbitrary numeric values to the to variable within your function causing the if(to){...} statement to execute if the passed value was anything but 0.
To fix this execute the swap() function without arguments in the setTimeout() like this:
var t = window.setTimeout(function(){ swap(); }, 1000);
Here is the updated demo: http://jsfiddle.net/x6PCD/14/
I hope this helps!

Related

set and clear interval multiple times

On the first slide of my slider I've got some text that changes within an interval.
This is the jQuery to do this:
<script>
var x = 0;
var text = ["STRATEGICALLY", "COST-EFFECTIVELY", "EFFICIENTLY", "EXCEPTIONALLY"];
var counter = 0;
var elem = document.getElementById("banner-change");
var intervalID = setInterval(change, 1500);
function change() {
jQuery(elem).fadeOut('slow', function() {
jQuery(elem).text(text[counter++]);
if (counter >= text.length) {
counter = 0;
}
jQuery(elem).fadeIn('fast');
if (++x === 5) {
window.clearInterval(intervalID);
}
});
}
</script>
The slider looks something like this (The shortened code):
<div id="myCarousel" class="hp-top carousel fade" data-ride="carousel" data-interval="6000">
<div class="carousel-inner">
<div class="item active"><img src="" alt="Chicago"/><div class="carousel-caption">
<div class="carousel-caption-inner">
<p class="slider-text small"><span class="slider-padding">What makes</span> us <span class="slider-green">specialists?</span></p>
<p class="slider-text">We just do ip</p>
<p class="slider-text"><span id="banner-change" class="slider-green">exceptionally</span></p>
</div>
</div>
</div>
So the words in <span id="banner-change" class="slider-green"> keep changing. This works fine. However, it only works for the first time the first banner is shown. Which makes sense as I'm clearing the interval as each word is only supposed to show once, but not sure how to do this so that every time the first banner shows it starts the interval again?
You can use the carousel evelts to trigger action.
e.relatedTarget will then refer to the slide, that is sliding into view.
So if you give it a unique id, you can identify it and run whatever action afterwards.
$('#myCarousel').on('slide.bs.carousel', function (e) {
if (e.relatedTarget.id === 'firstSlide') // do something
})

Stop simple JavaScript slideshow after one loop

I know very little about JavaScript at all, but I'm looking for a solution to a simple code that I'd like to use. I'm not trying to execute any slides or fades, just a simple slideshow that switches from one image to the next. I want the slideshow to play through just once, and then stop on the last image in the sequence. Any help would be greatly appreciated!
$("#slideshow > div:gt(0)").hide();
setInterval(function() {
$('#slideshow > div:first')
.next()
.end()
.appendTo('#slideshow');
}, 3000);
As I said, it's a very simple code. The first GIF runs only once, the second GIF loops. I would like the slideshow to stop on the looping GIF. I'm wondering if the '3000' (which I know corresponds to the length of each slide) can be changed to accomplish what I'm looking for. Or else adding a stop function... which I don't know how to write.
<div id="slideshow">
<div>
<img src="https://31.media.tumblr.com/e2c4bbaeb781a3b834cd09549595393f/
tumblr_noy3q3l1dy1uwyyx9o2_1280.gif">
</div>
<div>
<img src="https://33.media.tumblr.com/1d6495399687801067d62c83c4218644/
tumblr_noy3q3l1dy1uwyyx9o1_1280.gif">
</div>
</div>
Ok I have made this with the objective of being as clear and simple for you to understand as possible, (since you new to js...)
JS/Jquery:
$(function () {
setTimeout(playSlideShow, 3000);
function playSlideShow() {
var currImgContainer = $('.showImg');
if (!$(currImgContainer).hasClass('lastImg')) {
$('.showImg').removeClass('showImg').next().addClass('showImg');
setTimeout(playSlideShow, 3000);
}
}
});
So here we find the imgContainer(div) with the class "showImg", then using chaining, we remove the class and add it to the next imgContainer(div). Therefore toggling the CSS to show/hide the image until it finds the div that has the class "lastImg".
CSS:
.slideShow > div:not(.showImg) {
display: none;
}
.showImg {
display: block;
width: 400px;
height: 400px;
}
HTML:
<div class="slideShow" id="slideshow">
<div class="showImg">
<img src="Images/img1.png" alt="" />
</div>
<div>
<img src="Images/img2.png" alt="" />
</div>
<div>
<img src="Images/img3.png" alt="" />
</div>
<div class="lastImg">
<img src="Images/img4.png" alt="" />
</div>
</div>
This way you can have as many images as you want, just make sure the last div has class "lastImg" and the first one has the class "showImg".
Here is a fiddle
Hope it helps...
Try this:
var intervalID = null;
var iterator = 0;
var intervalDuration = 3000;
var slideshow = $('#slideshow');
var divs = slideshow.find('div');
//divs.filter(':gt(0)').hide();
divs.eq(iterator).show();
intervalID = setInterval(function(){
divs.eq(iterator).hide();
iterator += 1;
if (iterator === divs.length - 1) { clearInterval(intervalID); }
divs.eq(iterator).show();
}, intervalDuration);
#slideshow > div { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="slideshow">
<div>
<img src="https://dl.dropboxusercontent.com/u/45891870/Experiments/Codepen/PIXI/0.4/images/JS.jpg" />
</div>
<div>
<img src="https://dl.dropboxusercontent.com/u/45891870/Experiments/Codepen/PIXI/0.4/images/PIXI.jpg" />
</div>
<div>
<img src="https://dl.dropboxusercontent.com/u/45891870/Experiments/Codepen/PIXI/0.4/images/JS.jpg" />
</div>
</div>
The HTML structure is same as yours but the only thing that I have changed are the image sources (tumbler images weren't loading for me). But JavaScript has been changed completely.
Add as many DIVs as you like in your HTML to test it out. Hope it helps.
Update #1:
Added CSS to hide the divs by default.
Increased the intervalDuration to 3000. Just to make sure there is ample time for the images to be loaded.
Commented the filter line of JS.
Added another JS line right below the previous filter line.
This update should also load your GIF only when it is needed to appear, hence will not be running in the background.
Let me if this works.

How to set this "slider" to change every 5 seconds

I developed this "slider" in jQuery
HTML:
<div class="col-md-6 pos-rel text-center">
<div class="slider-meio slider1">
<img class="img-responsive" src="http://www.novahidraulica.com.br/imgcategoria/1/2014-09-24-11-09-0420.jpg">
</div>
</div>
<div class="col-md-6 pos-rel text-center">
<div class="slider-meio active slider2">
<img class="img-responsive" src="http://www.novahidraulica.com.br/imgcategoria/1/2014-09-24-11-09-0420.jpg">
</div>
</div>
<div class="col-md-3">
<ul class="controle-slider">
<li class="active-slider"><a data-target=".slider1" >LINHA FACE PLANA</a></li>
<li class=""><a data-target=".slider2" >LINHA COLHEDORA</a></li>
</ul>
</div>
JS:
function montaSlider() {
$(".slider-meio").each(function () {
if($(this).hasClass("active")){
$(this).fadeIn();
}else {
$(this).fadeOut();
}
});
}
montaSlider();
$(".controle-slider li a").click(function () {
$(".controle-slider li a").parent().removeClass("active-slider");
$(this).parent().addClass("active-slider")
$(".slider-meio").removeClass("active");
$($(this).attr("data-target")).addClass("active")
montaSlider();
});
i want to change the slide every 5 seconds, but i cant think of how to do it
can anyone help me?
You can use the window.setInterval() javascript method to call your montarSlider() every 5 seconds. Example:
var timer = window.seInterval(montarSlider, 5000);
I recommend you to store the variable returned by the setInterval() method so you can later stop it if necessary.
EDIT: Since you also need to rotate the elements with the active class, you can first make a function called slide() to activate the next element before calling the montarSlider() function. Then, instead of set the interval to the montarSlider() function, you set it to the slide() function. Example:
function slide() {
var currentActive = $(".slider-meio.active");
var nextActive;
currentActive.removeClass("active");
if(currentActive.parent().next().children(".slider-meio").length > 0) {
nextActive = currentActive.parent().next().children(".slider-meio");
} else {
nextActive = $(currentActive.parent().siblings()[0]).children(".slider-meio");
}
nextActive.addClass("active");
montaSlider();
}
var timer = window.seInterval(slide, 5000);
Use the setInterval() function:
var intrvl = setInterval(function(){montaSlider()},5000);
I you need to stop it use:
clearInterval(intrvl);

Two jQuery Animations on the same pages causes non smooth transitions

I have something like this
<hgroup id="ticker">
<div>
<h1>First <span>Div</span></h1>
<h2>This is the First Div</h2>
<h6>This is the First Heading</h6>
</div>
<div>
<h1>Second <span>Div</span></h1>
<h2>This is the Second Div</h2>
<h6>This is the Second Heading</h6>
</div>
<!-- And so on -->
</hgroup>
And I use
<script>
var $ticker = $('#ticker'); // save the static element
$ticker.children(':not(:first-child)').hide();
function tick(){
$ticker.children(':first-child').fadeOut(1000, function () {
$(this).appendTo($ticker);
$ticker.children().first().fadeIn(1000);
});
}
setInterval(tick, 8000);
</script>
It works ok. No problems with it. Maybe needs refactoring but I am just getting many hands dirty with jQuery. And Than I have
<div id="quote">
<blockquote>This is the First quote<span class="dim"><strong>1</strong></span></blockquote>
<blockquote>This is the First quote<span class="dim"><strong>1</strong></span></blockquote>
</div>
<!-- And so on -->
And I use
<script>
var $quote = $('#quote');
$quote.children(':not(:first-child)').hide();
function tick(){
$quote.children(':first-child').slideUp(1000, function () {
$(this).appendTo($quote);
$quote.children().first().slideDown(1000);
});
}
setInterval(tick, 8000);
</script>
But what this does is that the animation is not smooth. The fade and slide pauses, resumes, flickers and the animation/transition is not smooth or fluid.
Any single one without the other works ok but taken together on the same pages causes this issue.
Also note I can half understand the jQuery code above.
Working DEMO
Try this,
var $quote = $('#quote');
$quote.children(':not(:first-child)').hide();
function tick() {
$quote.children(':first-child').stop().slideUp(1000, function () {
$(this).appendTo($quote);
$quote.children().stop().first().slideDown(1000);
});
}
setInterval(tick, 8000);

Why is jQuery fadeIn effect not working when I reverse the order?

I am trying to implement fadein effect for the picture, where there's picture 1, 2 and 3. When I fadeIn picture following sequence, the fadeIn effect works. However, if I click the picture link in backward, example picture 3 then picture 2, you won't see the fadeIn effect. Not sure what mistake I did here.
Here's the code:
<html>
<head>
<script src='http://code.jquery.com/jquery-1.6.2.min.js' type='text/javascript'></script>
<style type="text/css">
#wrapper{
width:400px;
height:300px;
}
.picture{
width:400px;
height:300px;
position:absolute;
}
.button{
background-color:red;
width:300px;
height:200px;
}
</style>
<script type="text/javascript">
function switchPicture(id){
visible_image_id = jQuery("img:visible").attr("id");
jQuery("#image_"+id).fadeIn(500,function(){
console.log("visible -" + visible_image_id);
jQuery("#"+visible_image_id).hide();
});
}
</script>
</head>
<body>
<div id='wrapper'>
<img id='image_1' class='picture' style="display:block;" src="http://media.smashingmagazine.com/wp-content/uploads/uploader/images/wallpaper-calendar-august-11/lion__11.jpg">
<img id='image_2' class='picture' style="display:block;" src="http://media.smashingmagazine.com/wp-content/uploads/uploader/images/wallpaper-calendar-august-11/before_the_fall__39.jpg">
<img id='image_3' class='picture' style="display:block;" src="http://media.smashingmagazine.com/wp-content/uploads/uploader/images/wallpaper-calendar-august-11/hot_august__97.jpg">
</div>
<div>
Picture 1
Picture 2
Picture 3
</div>
</body>
</html>
You have a z-index issue. The problem is that if you are say, showing image 2 with image 3 already shown. Image 3 is in front of image 2, so you will not see image 2 until 3 is hidden. 3 isn't hidden until after the fade completes. You can fix this by setting the z-index of the images.
function switchPicture(id) {
visible_image_id = jQuery("img:visible").css("zIndex", 0).attr("id");
jQuery("#image_" + id).fadeIn(500, function() {
console.log("visible -" + visible_image_id);
jQuery("#" + visible_image_id).hide();
}).css("zIndex", 1);
}
http://jsfiddle.net/7kQWG/
EDIT: Some additional improvements. You should ideally get rid of the inline javascript in the href and replace it with a click handler. Something like this:
$(function() {
$("a").click(function() {
var visible_image_id = jQuery("img:visible").css("zIndex", 0).attr("id");
var new_image_id = "image_" + ($(this).index() + 1);
if(visible_image_id == new_image_id) return false;
jQuery("#" + new_image_id).fadeIn(500, function() {
console.log("visible -" + visible_image_id);
jQuery("#" + visible_image_id).hide();
}).css("zIndex", 1);
return false;
});
});
http://jsfiddle.net/7kQWG/1
Also note, I added if(visible_image_id == new_image_id) return false;. This will fix the bug where it was hiding the image entirely if you clicked on the link of the visible image.
For extra bonus points, you can replace the href with a URL to a no-javascript page. That way if the user doesn't have javascript enabled, they will be taken to that page but if javascript is on the intended behavior will occur.

Categories

Resources