'use strict';
$(function () {
var currentSlide = 1;
//DOM cache
var $slider = $('#slider');
var $slidesContainer = $slider.find('#container');
var $slides = $slidesContainer.find("li")
console.log($slides.length);
//slider
setInterval(slide, 3000);
function slide() {
$slidesContainer.animate({'margin-left': '-='+400}, 800);
console.log(currentSlide);
currentSlide++;
if (currentSlide === $slides.length) {
currentSlide = 1;
$slidesContainer.css("margin-left", 0);// <------PROBLEM HERE
}//end if
}//end slide
});//end js
This slider is almost good but I don't know why this method .css() is not working. If is working because variable currentSlide is going to 1 when equals 4 ($slides.length).
Thanks for all answers.
You should wait for animation to complete, use its callback method.
$slidesContainer.animate({
'margin-left': '-=' + 400
}, 800, function() {
// Animation complete.
currentSlide++;
if (currentSlide === $slides.length) {
currentSlide = 1;
$slidesContainer.css("margin-left", 0);
}
});
Related
I'm trying to create a simple JQuery slider, and I'm having trouble with the .on('click') function, if I click the next or prev button too fast it exceeds the value I expect.
var currentSlide = 1;
var $slider = $(".slides");
var slideCount = $slider.children().length;
var slideSpeed = 500;
var slideMarginLeft = -900;
var slideMarginRight = 0;
$(".prev").on('click',function(){
if(currentSlide > 1){
$slider.animate({marginLeft : slideMarginLeft + 1800} , slideSpeed, function(){
slideMarginLeft +=900;
currentSlide--;
console.log(currentSlide);
});
}
});
$(".next").on('click',function(){
if(currentSlide < 5){
$slider.animate({marginLeft : slideMarginLeft} , slideSpeed, function(){
slideMarginLeft -=900;
currentSlide++;
console.log(currentSlide);
});
}
});
var currentSlide = 1;
var $slider = $(".slides");
var slideCount = $slider.children().length;
var slideSpeed = 500;
var slideMarginLeft = -900;
var slideMarginRight = 0;
function previousClickCallback(animationCallback){
return function(){
if(currentSlide > 1){
$slider.animate({marginLeft : slideMarginLeft + 1800} , slideSpeed, () => {
slideMarginLeft +=900;
currentSlide--;
console.log(currentSlide);
$(".prev").once('click',previousClickCallback);
});
} else {
$(".prev").one('click',previousClickCallback);
}
}
}
function nextClickCallback(){
return function(){
if(currentSlide < 5){
$slider.animate({marginLeft : slideMarginLeft} , slideSpeed, () => {
slideMarginLeft -=900;
currentSlide++;
console.log(currentSlide);
$(".next").once('click',nextClickCallback);
});
} else {
$(".next").one('click',nextClickCallback);
}
}
}
$(".prev").one('click',previousClickCallback);
$(".next").one('click',nextClickCallback)
This should do, click event gets registered only once and once the callback for animation is done then only click event is registered again and that will stop from continuously firing events
Make sure the .next class is assigned to only one button.
I cant get my head around this, been trying many many different ways but no luck.. Basically, I'm trying to pause the animation on mouseOver and resume it on mouseOut. I was able to make it pause by simply using clearTimeout() but I have no idea on how to resume it back on. Please kindly advise me with a correct solution and syntax.
Thank you in advance!
(function ($) {
$.fn.simpleSpy = function (interval, limit) {
limit = limit || 3;
interval = interval || 3000;
items = [];
return this.each(function () {
$list = $(this),
currentItem = 0,
total = 0; // initialise later on
var i = 0;
smplet = $list.clone();
smplet.css("display","none");
$("body").append(smplet);
total = smplet.find('> li').length;
$list.find('> li').filter(':gt(' + (0) + ')').remove();
$list.css("display","");
height = $list.find('> li:first').height();
$list.wrap('<div class="spyWrapper" />').parent().css({ height : 55, position:"relative", overflow:"hidden" });
$('.close').click(function(){
clearTimeout(timec);
if(currentItem == 0 && smplet.length != 1)
delitem=total;
else
delitem=currentItem - 1;
smplet.find('> li').eq(delitem).remove();
currentItem--;
var temp=smplet.find('> li').eq(currentItem).clone();
var $insert = temp.css({
"margin-top":-height-height/3,
opacity : 0
}).prependTo($list);
// fade the LAST item out
$list.find('> li:last').animate({ opacity : .5 ,"margin-top":height/3}, 500, function () {
$(this).remove();
});
$insert.animate({"margin-top":0,opacity : 1 }, 500).animate({opacity : 1},1000);
currentItem++;
total=smplet.find('> li').length;
if (currentItem >= total) {
currentItem = 0;
}
if (total == 1){
simpleSpy.stop();
}
else if(total == 0){
$("#topbar").hide();
}
timec=setTimeout(spy, interval);
});
currentItem++;
function spy() {
var temp=smplet.find('> li').eq(currentItem).clone();
var $insert = temp.css({
"margin-top":-height-height/3,
opacity : 0,
display : 'none'
}).prependTo($list);
$list.find('> li:last').animate({ opacity : .5 ,"margin-top":height/3}, 500, function () {
$(this).remove();
});
$insert.animate({"margin-top":0,opacity : 1 }, 500).animate({opacity : 1},1000);
$insert.css("display","");
currentItem++;
if (currentItem >= total) {
currentItem = 0;
}
timec=setTimeout(spy, interval);
}
timec=setTimeout(spy, interval);
});
};
$('ul.alerts')
.mouseover(function(){
clearTimeout(timec);
})
.mouseout(function(){
timec=setTimeout(spy, interval);
});
})(jQuery);
Call
$(document).ready(function() {
$('ul.alerts').simpleSpy();
});
jsfiddle with html and css
http://jsfiddle.net/1781367/3eK4K/3/
I changed the timeout, which you were setting over and over, to an interval, which you only need to set once. Then I added a "paused" property that is set to true on mouseover and back to false on mouseout.
var paused = false;
$list.mouseover(function() { paused = true; });
$list.mouseout(function() { paused = false; });
Then we just check that property before the rotation animation occurs:
if (paused) {
return;
}
http://jsfiddle.net/3eK4K/6/
I want my slider to show "slide 1" after "slide 3" and not that after "slide 3" you are forced to use the return or previous button. I am a leak in javascript so I was wondering if someone could help me out for a sec ;)
And I was wondering how to make this one a width of 100% so it is more or less responsive :)
$(document).ready(function() {
// Your code from above goes here
var sliderWidth = 1280;
var slider = $('#slidiemain');
var sliderCount = $('div', slider).length;
slider.width(sliderCount * sliderWidth);
var currentSlide = 1;
$('a.prev1').click(function () {
if (currentSlide > 1) {
$('#slidiemain').animate({
left: '+=' + sliderWidth
}, 700);
currentSlide -= 1;
}
});
$('a.next1').click(function () {
if (currentSlide < sliderCount) {
$('#slidiemain').animate({
left: '-=' + sliderWidth
}, 700);
currentSlide += 1;
}
});
});
I am not familiar with the slideshow plugin you are using, but this should work:
$(document).ready(function() {
// Your code from above goes here
var sliderWidth = $( window ).width(); // Get the width of browser window
var slider = $('#slidiemain');
var sliderCount = $('div', slider).length;
slider.width(sliderCount * sliderWidth);
var currentSlide = 1;
$('a.prev1').click(function () {
if (currentSlide > 1) {
$('#slidiemain').animate({
left: '+=' + sliderWidth
}, 700);
currentSlide -= 1;
}
});
$('a.next1').click(function () {
if (currentSlide < sliderCount) {
$('#slidiemain').animate({
left: '-=' + sliderWidth
}, 700);
currentSlide += 1;
}
else
{
$('#slidiemain').animate({left: '+=' + (2*sliderWidth)}, 1);
currentSlide = 1;
}
});
});
I have this javascript function I use that when clicked goes a certain distance. This is used within a scroller going left to right that uses about 7 divs. My question is how do I get the click to go the full distance first before the click can be used again? The issue is if the user rapidly clicks on the arrow button it resets the distance and sometimes can end up in the middle of an image instead of right at the seam. What code am I missing to accomplish this?
$(function () {
$("#right, #left").click(function () {
var dir = this.id == "right" ? '+=' : '-=';
$(".outerwrapper").stop().animate({ scrollLeft: dir + '251' }, 1000);
});
});
I would've thought that the easiest way would be to have a boolean flag indicating whether or not the animation is taking place:
$(function () {
var animating = false,
outerwrap = $(".outerwrapper");
$("#right, #left").click(function () {
if (animating) {return;}
var dir = (this.id === "right") ? '+=' : '-=';
animating = true;
outerwrap.animate({
scrollLeft: dir + '251'
}, 1000, function () {
animating = false;
});
});
});
works for me: http://jsfiddle.net/BYossarian/vDtwy/4/
Use .off() to unbind the click as soon as it occurs, then re-bind it once the animation completes.
function go(elem){
$(elem).off('click'); console.log(elem);
var dir = elem.id == "right" ? '+=' : '-=';
$(".outerwrapper").stop().animate({ left: dir + '251' }, 3000, function(){
$("#right, #left").click(go);
});
}
$("#right, #left").click(function () {
go(this);
});
jsFiddle example
You can see in this simplified example that the click event is unbound immediately after clicking, and then rebound once the animation completes.
Use an automatic then call like this
var isMoving = false;
$(function () {
$("#right, #left").click(function () {
if (isMoving) return;
isMoving = true;
var dir = this.id == "right" ? '+=' : '-=';
$(".outerwrapper").stop().animate({ scrollLeft: dir + '251' }, 1000).then(function(){isMoving = false}());
});
});
I think that you miss the fact that when you make stop() you actually position the slider at some specific point. I.e. if your scroller is 1000px and you click left twice very quickly you will probably get
scrollLeft: 0 - 251
scrollLeft: -2 - 251
So, I think that you should use an index and not exactly these += and -= calculations. For example:
$(function () {
var numberOfDivs = 7;
var divWidth = 251;
var currentIndex = 0;
$("#right, #left").click(function () {
currentIndex = this.id == "right" ? currentIndex+1 : currentIndex-1;
currentIndex = currentIndex < 0 ? 0 : currentIndex;
currentIndex = currentIndex > numberOfDivs ? numberOfDivs : currentIndex;
$(".outerwrapper").stop().animate({ scrollLeft: (currentIndex * divWidth) + "px" }, 1000);
});
});
A big benefit of this approach is that you are not disabling the clicking. You may click as many times as you want and you can do that quickly. The script will still works.
This will work perfectly fine:
var userDisplaysPageCounter = 1;
$('#inventory_userdisplays_forward_button').bind('click.rightarrowiventory', function(event) {
_goForwardInInventory();
});
$('#inventory_userdisplays_back_button').bind('click.leftarrowiventory', function(event) {
_goBackInInventory();
});
function _goForwardInInventory()
{
//$('#inventory_userdisplays_forward_button').unbind('click.rightarrowiventory');
var totalPages = $('#userfooterdisplays_list_pagination_container div').length;
totalPages = Math.ceil(totalPages/4);
// alert(totalPages);
if(userDisplaysPageCounter < totalPages)
{
userDisplaysPageCounter++;
$( "#userfooterdisplays_list_pagination_container" ).animate({
left: "-=600",
}, 500, function() {
});
}
}
function _goBackInInventory()
{
//$('#inventory_userdisplays_back_button').unbind('click.leftarrowiventory');
if(userDisplaysPageCounter > 1)
{
userDisplaysPageCounter--;
$( "#userfooterdisplays_list_pagination_container" ).animate({
left: "+=600",
}, 500, function() {
});
}
}
I second BYossarian's answer.
Here is a variation on his demo, which "skips" the animation when the user clicks several times quickly on the buttons :
$(function () {
var targetScroll = 0,
outerwrap = $(".outerwrapper");
$("#right, #left").click(function () {
// stop the animation,
outerwrap.stop();
// hard set scrollLeft to its target position
outerwrap.scrollLeft(targetScroll*251);
if (this.id === "right"){
if (targetScroll < 6) targetScroll += 1;
dir = '+=251';
} else {
if (targetScroll > 0) targetScroll -=1;
dir = '-=251';
}
outerwrap.animate({ scrollLeft: dir }, 1000);
});
});
fiddle
I have found this nice js slider that works by clicking on radio buttons, selecting the slides to view.
I'd like it to autoplay the slides, and give it a time for slides and transitions, but I'm honestly unsure where to put those values.
I've seen the other questions about similar problems, but couldn't find a proper answer to my problem. Help, please?
<script type="text/javascript">
$(document).ready(function () {
var showCaseItems = $('.show-case-item').hide();
var splashes = $('.splash').hide();
//get each image for each slide and set it as a background of the slide
// splashes.each(function () {
// var img = $(this).find('img');
// var imgSrc = img.attr('src');
// img.css('visibility', 'hidden');
// $(this).css({ 'background-image': 'url(' + imgSrc + ')', 'background-repeat': 'no-repeat' });
// });
splashes.eq(0).show();
showCaseItems.eq(0).show();
var prevIndex = -1;
var nextIndex = 0;
var currentIndex = 0;
$('#banner-pagination li a').click(function () {
nextIndex = parseInt($(this).attr('rel'));
if (nextIndex != currentIndex) {
$('#banner-pagination li a').html('<img src="assets/img/slidedot.png" alt="slide"/>');
$(this).html('<img src="assets/img/slidedot-active.png" alt="slide"/>');
currentIndex = nextIndex;
if (prevIndex < 0) prevIndex = 0;
splashes.eq(prevIndex).css({ opacity: 1 }).animate({ opacity: 0 }, 500, function () {
$(this).hide();
});
splashes.eq(nextIndex).show().css({ opacity: 0 }).animate({ opacity: 1 }, 500, function () { });
showCaseItems.eq(prevIndex).css({ opacity: 1 }).animate({ opacity: 0 }, 500, function () {
$(this).hide();
showCaseItems.eq(nextIndex).show().css({ opacity: 0 }).animate({ opacity: 1 }, 200, function () { });
});
prevIndex = nextIndex;
}
return false;
});
});
</script>
You can use jquery and setTimeout
setTimeout(function() {$('#banner-pagination li a').trigger('click');}, 1500);
this code will loop every 1.5 seconds and trigger a click on #banner-pagination li a
you can use the jquery trigger event and hit the radio button click event forcefully
$('#foo').trigger('click');
http://api.jquery.com/trigger/
setInterval(function()
{$('#banner-pagination li a[rel='+((currentIndex+1)%3)+']').trigger('click');},5000);
Thanks