I got this wonderful pieve of code to auto update my thumbnails on click and on bs.slide function. It works properly when auto updating via the timer interval, clicking the next arrow, or clicking on the respective thumbnail in the carousel.
$('#myCarousel').carousel({
interval: 4000
});
var selectorIdx = 1;
var numItems = 12;
// handles the carousel thumbnails
$('.carousel-selector').click(function () {
selectorIdx = $(this).closest('li').index();
$('#myCarousel').carousel(selectorIdx)
});
$('#myCarousel').on('slide.bs.carousel', function () {
$('#myCarousel')
.find('.carousel-selector')
.removeClass('selected')
.eq(selectorIdx).addClass('selected')
.end()
.find('.item').removeClass('selected')
.eq(selectorIdx).addClass('active');
if (selectorIdx < (numItems - 1)) {
selectorIdx++;
}
else {
selectorIdx = 0;
}
});
However the carousel thumbs do not auto update when the prev arrow is clicked, how can this code be updated to reflect that action?
Rough Fiddle, you can see when you hit the prev arrow the thumbs still update going forward instead of backward.
http://jsfiddle.net/gward90/xr8qzxmg/12/
Thank You
Here is how I would change your code to select the thumbnail. http://jsfiddle.net/xr8qzxmg/15/
$('#myCarousel').on('slide.bs.carousel', function (e) {
selectorIdx = $(e.relatedTarget).index();
$(this)
.find('.carousel-selector').removeClass('selected')
.eq(selectorIdx).addClass('selected')
.end()
.find('.item').removeClass('selected')
.eq(selectorIdx).addClass('active');
});
Related
I have a slider with arrows. When I click on these arrows a lot of times, the slider continually slides depending on how many times I click the arrow. How do you prevent clicking on the arrow until the sliding animation is done?
Please see what I mean in my pen here: http://codepen.io/gianaguilar/pen/JGaxKL
Try clicking on the arrows multiple times and how the slider responds. I need to be able to slide one click at a time.
Thank you!
Here is the jquery code
var $visibleSlide, getDataSlide, sliderInterval, getDataNextSlide, getDataPrevSlide, getDataNavDot;
var fadeDuration = 1000;
var pause = 8000;
//show first slide
$('.slides li:first-child').css('display', 'block');
//show first nav dot
$('.nav li:first-child').addClass('active-cd');
//find out what slide is visible and get its data attribute
function getSlideInfo() {
$visibleSlide = $('.slides').find('li:visible');
getDataSlide = $visibleSlide.data('n');
getDataNextSlide = $visibleSlide.next().data('n');
getDataPrevSlide = $visibleSlide.prev().data('n');
}
//show next slide
function showNextSlide() {
getSlideInfo();
$('.nav li').removeClass('active-cd');
if (getDataSlide < 3) {
$visibleSlide.fadeOut(fadeDuration);
$visibleSlide.next().fadeIn(fadeDuration);
$('.nav li[data-cd=' + getDataNextSlide + ']').addClass('active-cd');
} else {
$visibleSlide.fadeOut(fadeDuration);
$('.slides li:first-child').fadeIn(fadeDuration);
$('.nav li:first-child').addClass('active-cd');
}
} //end showNextSlide
function showPrevSlide() {
getSlideInfo();
$('.nav li').removeClass('active-cd');
if (getDataSlide > 1) {
$visibleSlide.fadeOut(fadeDuration);
$visibleSlide.prev().fadeIn(fadeDuration);
$('.nav li[data-cd=' + getDataPrevSlide + ']').addClass('active-cd');
} else {
$visibleSlide.fadeOut(fadeDuration);
$('.slides li:last-child').fadeIn(fadeDuration);
$('.nav li:last-child').addClass('active-cd');
}
} // end showPrevSlide
// controls
$('.next').on('click', showNextSlide);
$('.prev').on('click', showPrevSlide);
//autoplay
function startSlider() {
sliderInterval = setInterval(showNextSlide, pause)
}
startSlider();
$('.slideshow').mouseenter(function() {
clearInterval(sliderInterval);
});
$('.slideshow').mouseleave(startSlider);
//control dots clicks
$('.nav li').on('click', function() {
getDataNavDot = $(this).data('cd');
getSlideInfo();
$('.nav li').removeClass('active-cd');
$(this).addClass('active-cd');
$visibleSlide.fadeOut(fadeDuration);
$('.slides li[data-n=' + getDataNavDot + ']').fadeIn(fadeDuration);
}); //end dots click
You can define a variable isAnimating that is set to true when you are in the next or previous slide function, and set to false when the animation is complete (within a callback function to one of your fade functions).
A simple check at the top of these next and previous functions to return false if the isAnimating function is set to true will prevent the animations from queuing up.
See here: http://codepen.io/anon/pen/XXPOQY
I am struggling to find a solution to repeat action when user did already one time. For example, when user comes on site there is carousel which can be swiped, slided, and eventually opened in order to see full gallery. I have managed to do that but when the user made this action and closes modal box, he is not able to repeat the same action. Anyone has idea how to solve it?
Here is js
$(document).ready(function () {
// - jQuery
// Swipe feature
$('#myCarousel').swiperight(function () {
$('#myCarousel').carousel('prev');
});
$('#myCarousel').swipeleft(function () {
$('#myCarousel').carousel('next');
});
// Swipe feature for modal
$('#modal-carousel').swiperight(function () {
$('#modal-carousel').carousel('prev');
console.log('swipe_right');
});
$('#modal-carousel').swipeleft(function () {
$('#modal-carousel').carousel('next');
console.log('swipe_left');
});
// Additional toolbar with "close" button appears
$(window).on('shown.bs.modal', function () {
$('modal').modal('show');
$('#toolbar').css('display', 'block'); //.css('position','fixed')
$('.carousel-inner').css('overflow', 'visible');
// Remove entirely in final version
$('.item').css('background', 'none')
console.log('fires toolbar');
});
$(window).on('hidden.bs.modal', function () {
$('modal').modal('show');
$('#toolbar').css('display', 'none'); //.css('position','absolute')
$('.carousel-inner').css('overflow', 'hidden');
// Remove entirely in final version
$('.item').css('background', '#60b1ff')
console.log('closes toolbar when modal is closed');
});
// Closes modal on toolbar
$('.trigger').click(function () {
$('.modal').modal('hide');
});
/* Modal Carousel from version 3. adjusted to version 2.3 */
/* activate the carousel */
$("#modal-carousel").carousel({
interval : false,
});
/* when clicking a image */
$(".thumbnail").click(function () {
var content = $(".carousel-inner");
content.empty();
var id = this.id;
var repo = $('#img-repo .item');
var repoCopy = repo.filter('#' + id).clone();
var active = repoCopy.first();
var next = repoCopy.last();
active.addClass('active');
content.append(repoCopy);
// show the modal
$('#modal-gallery').modal('show');
});
// Carousel pause - prevents automatic slideshow
$('.carousel').carousel({
pause : true,
interval : false
});
// Close window
$('.modal-backdrop').modal({
show : false
});
}); //end of script
Problem is at the content.empty(); which after executed action stays empty. Any ideas how to solve this?
Fiddle
Fiddle 2 with working carousel. Just imagine that you are able to open one of those images in modal.
I'm am attempting to build a homepage that has animations. I am having hard time controlling my animations though. All I need is to hide elements, and then show elements after a certain time. Loop through that sequence, and pause and show all elements when the someone hovers over the box. Example simple animation.
I have a long way to go. At first I tried using the .css() visibility property, now I'm using .show() and .hide().
I need a way to loop through my animations. I attempt to add another
setTimeout(clear1(), 3000);
to the end of my box1 function, but that wouldn't work for some reason.
I need a way to on a user hover over #box1, that all animations stop. I have tried using .clearQueue, but I couldn't get that to work.
First of all, set to your css:
.box {display: none;}
SHOW ALL BOXES ON HOVER See Demo
This will show all boxes on hover and then continue the animation from where it stopped (will hide the boxes that hadn't shown up during the animation). I think that is what you are after.
var index = 0; // To keep track of the last div showed during animation
var time_of_delay = 1000; // Set the time of delay
// Start the animation
$(document).ready(function () {
box1(time_of_delay);
});
// The hover states
$("#box1_1").hover(
function() {
box1(0);
}, function() {
box1(time_of_delay);
});
// The animation function
function box1 (delay_time) {
var time=delay_time;
if(time>0) {
$(".box").slice(index).each(function() {
$(this).hide().delay(time).show(0);
time=time+time_of_delay;
});
index=0;
} else {
$(".box:visible").each(function() {
index++;
});
$(".box").stop(true).show(0);
}
}
PAUSE ON HOVER See Demo
This will only pause the animation and continue from where it stopped.
var time_of_delay = 1000; // Set the time of delay
// Start the animation
$(document).ready(function () {
box1(time_of_delay);
});
// The hover states
$("#box1_1").hover(
function() {
box1(0);
}, function() {
box1(time_of_delay);
});
// The animation function
function box1 (delay_time) {
var time=delay_time;
if(time>0) {
$(".box:hidden").each(function() {
$(this).delay(time).show(0);
time=time+time_of_delay;
});
} else {
$(".box").stop(true);
}
}
I used setTimeout and clearTimeout and periodically call a function that increments (and resets) the box to display. Since I assign setTimout to boxt, I am able to call clearTimeout(boxt) on box1's hover event so that I can stop specifically that loop. Here's my jsfiddle. It might not be the exact effect you're trying to achieve, but it should be the right functionality and be easily adaptable with a few tweaks. Let me know if this works for you and if you have any questions about how it works :)
LIVE DEMO
var $box = $('#box1').find('.box'),
boxN = $box.length,
c = 0,
intv;
$box.eq(c).show(); // Show initially the '0' indexed .box (first one)
function loop(){
intv = setInterval(function(){
$box.eq(++c%boxN).fadeTo(400,1).siblings().fadeTo(400,0);
},1000);
}
loop(); // Start your loop
$('#box1').on('mouseenter mouseleave', function( e ){
return e.type=='mouseenter' ? (clearInterval(intv))($box.fadeTo(400,1)) : loop();
});
Where ++c%boxN will take care to loop your animation using the Modulo % (reminder) operator inside a setInterval. Than all you need to do is to register a mouseenter and mouseleave on the parent element to:
clear the Interval on mouseenter + fade all your elements
restart your loop function on mouseleave.
Here's one way to do it:
// hide all of the boxes
$('.box').hide();
// reference to each box, the current box in this list and a flag to stop the animation
var divs = box1.getElementsByClassName('box');
var i = 0;
var run = true;
// this will animate each box one after the other
function fade(){
if(i < divs.length && run){
$(divs[i++]).fadeIn(500, function(){
setTimeout(fade, 1000);
});
}
};
fade();
// stop the above function from running when the mouse enters `box1`
$('#box1').on('mouseenter', function(){console.log('enter');
run = false;
});
// start the function again from where we stopped it when the mouse leaves `box1`
$('#box1').on('mouseleave', function(){console.log('leave');
run = true;
fade();
});
Demo: http://jsfiddle.net/louisbros/dKcn5/
The Bootstrap carousel is a strange beast. I've tried tweaking $next to prevent infinite looping but end up either breaking it or preventing the slides from going backwards when reaching the end.
I would like the carousel to only slide within the list and not infinitely loop.
Any help would be appreciated.
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
if ($next.hasClass('active')) return
if ($.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
this.$element.one($.support.transition.end, function() {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function() {
that.$element.trigger('slid')
}, 0)
})
} else {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger('slid')
}
Update: This is unrelated to "autoplay" I'm specifically referring to manually pressing the left and right buttons.
For the carousel to not infinitely loop (using Bootstrap 3.0.0), and stop at the last slide unless the "next" arrow is clicked, the following is the best way to do it:
$('.carousel').carousel({
interval: 5000,
wrap: false
});
Setting the wrap option to false tells the carousel to stop cycling through the slides automatically. I hope this answers your question correctly.
You could just add some code to the page to hide the appropriate carousel controls after a slid event:
$('#myCarousel').on('slid', '', function() {
var $this = $(this);
$this.children('.carousel-control').show();
if($('.carousel-inner .item:first').hasClass('active')) {
$this.children('.left.carousel-control').hide();
} else if($('.carousel-inner .item:last').hasClass('active')) {
$this.children('.right.carousel-control').hide();
}
});
This example assumes the markup used on the Twitter Bootstrap example carousel.
Make sure to hide the left one when you open the page.
Add attribute data-wrap="false" in Div
The easiest way to do this is as follows:
//intro slider
$('#carousel_fade_intro').carousel({
interval: 2500,
pause: "false"
})
//Stop intro slider on last item
var cnt = $('#carousel_fade_intro .item').length;
$('#carousel_fade_intro').on('slid', '', function() {
cnt--;
if (cnt == 1) {
$('#carousel_fade_intro').carousel('pause');
}
});
Not sure if this is only relevent to the newest version of Bootstrap but setting data-wrap="false" on the outermost carousel container will prevent it from proceeding past the final slide.
source: http://getbootstrap.com/javascript/#carousel-options
For people looking for a solution for Bootstrap 3 working for multiple carousels on same page try this:
$(function() {
// init carousel
$('.carousel').carousel({
pause: true, // init without autoplay (optional)
interval: false, // do not autoplay after sliding (optional)
wrap:false // do not loop
});
// init carousels with hidden left control:
$('.carousel').children('.left.carousel-control').hide();
});
// execute function after sliding:
$('.carousel').on('slid.bs.carousel', function () {
// This variable contains all kinds of data and methods related to the carousel
var carouselData = $(this).data('bs.carousel');
// get current index of active element
var currentIndex = carouselData.getItemIndex(carouselData.$element.find('.item.active'));
// hide carousel controls at begin and end of slides
$(this).children('.carousel-control').show();
if(currentIndex == 0){
$(this).children('.left.carousel-control').fadeOut();
}else if(currentIndex+1 == carouselData.$items.length){
$(this).children('.right.carousel-control').fadeOut();
}
});
Please let me now if this is not working in your case.
if you are using bootstrap 3 use this
$('.carousel').carousel({
wrap: false
});
The codes posted here have two problems: doesn't work if you have more than one carousel on the same page and doesn't work if you click on the indicator dots. Also, in Bootstrap 3 the event has changed name.
The below code is an updated version of this code. And here you can find a more detailed explanation
checkitem = function() {
var $this;
$this = $("#slideshow");
if ($("#slideshow .carousel-inner .item:first").hasClass("active")) {
$this.children(".left").hide();
$this.children(".right").show();
} else if ($("#slideshow .carousel-inner .item:last").hasClass("active")) {
$this.children(".right").hide();
$this.children(".left").show();
} else {
$this.children(".carousel-control").show();
}
};
checkitem();
$("#slideshow").on("slid.bs.carousel", "", checkitem);
I'm creating a feature content slider using jQuery and I have hit a few snags trying to get rid of the last few bugs. It is inspired by http://kleientertainment.com/ so check it out and you'll see what im going for. Any suggestions on achieving this effect even with totally new code would be helpful!
The idea is a simple div swap, but with custom animations for each slide that fire when it is loaded. It also MUST fade to black in between each transition, whether autoplay or clicked.
lets get to the code and bugs:
$(document).ready(function () {
//START SLIDES HIDDEN
$('.slide').css({
'position': 'absolute',
'display': 'none'
});
//RUN FIRST SLIDE
runSlideShow(1);
animation1_swap();
//AUTOPLAY FUNCTION
function runSlideShow(slideNumber) {
$('#slide' + slideNumber).fadeIn(1000).delay(10000).fadeOut(1000, function () {
if (slideNumber == 4) {
animation1_swap();
runSlideShow(1);
}
if (slideNumber == 3) {
animation4_swap();
runSlideShow(4);
}
if (slideNumber == 2) {
animation3_swap();
runSlideShow(3);
}
if (slideNumber == 1) {
animation2_swap();
runSlideShow(2);
}
});
//NAVIGATION BUTTONS
$('#bullet1').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation1_swap();
runSlideShow(1);
});
});
$('#bullet2').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation2_swap();
runSlideShow(2);
});
});
$('#bullet3').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation3_swap();
runSlideShow(3);
});
});
$('#bullet4').click(function () {
$('.slide:visible').stop(true, true).fadeOut(1000, function () {
animation4_swap();
runSlideShow(4);
});
});
}
});
CSS info: .slide sets the dimensions, and #slideX are the individual background images for each. #bulletX are the nav buttons.
Also, the animationX_swap() are the animations specific to that slide. They live in another file and would have made this post way too long.
The bugs:
Right now, the autoplay function is great, you can watch it all day and not see a hiccup. The trouble comes when the nav buttons are used, particularly #bullet1. If i click #bullet1, then go to 2, then back to 1, the autoplay seems to be sped up as the slide fades out before it is supposed to. I am a total beginner but I made it this far, can anyone help me clean this up and essentially reimagine http://kleientertainment.com/ 's slider?
Just discovered jQuery cycle plugin http://malsup.com/jquery/cycle/ from another post.
I remade my slider with that and it preforms exactly as needed. Good stuff!