I am trying to create a customized carousel and it already has the following features:
You can move left and right with the mouse or by swipe on mobile/tablets.
You can move left or right with buttons.
However, the problem is that the buttons don't deactivate once the end of the div is reached. Instead, everything keeps shifting forever. See picture below:
Take a look at the jsFiddle: http://jsfiddle.net/vnkRw/2/
$("#left").click(function() {
$(".wrapper").stop(true, true).animate({left: "-=125px"}, 500);
});
$("#right").click(function() {
$(".wrapper").stop(true, true).animate({left: "+=125px"}, 500);
});
How can I deactivate the buttons once the end is reached? For example, when here:
The left button should deactivate since there are no more div's to show.
And, of course, the same for the right:
The Goal: Deactive buttons when end is reached.
something like
pos=slides=$(".wrapper > div").length;
$("#left").click(function() {
if(pos>3){$(".wrapper").stop(true, true).animate({left: "-=125px"}, 500);pos--;}
});
$("#right").click(function() {
if(pos<slides){$(".wrapper").stop(true, true).animate({left: "+=125px"}, 500);pos++;}
});
$('.carousel').kinetic();
There are some things to consider when doing carousel, I'll just get you started.
Will all items be the same width
Will all items have same margins
Will the things above be variable
It we presume that all the things above are static, the idea is for the scroll to right to not happen if the left position of wrapper is 0. And that's the easy part. For the other direction you have to take the number of all items, subtract the number of visible items (in your case 3) , multiply that by their width (including the margin) and all this providing all items are same width and with same margin .. and in the end you have to multiply that by -1, because your wrapper's left position becomes negative number. And in the end, if wrapper reached that position, you should not scroll it.
A visualization of the above mini-wall of text:
http://jsfiddle.net/vnkRw/4/
Related
I'm trying to make an image carousel/slider that automatically scrolls smoothly and loops using jQuery. Here's the function I'm using:
function spinCarousel() {
$("ul li:first-child").animate({ marginLeft: -200 }, 3000, 'linear', function () {
$("ul li:first-child").appendTo('ul');
$("ul li:last-child").css('margin-Left', 0);
spinCarousel();
});
}
And here's an illustration: https://jsfiddle.net/T_Recks/aa43n7g0/
I tried adding it to a local development site (replacing the text and colored backgrounds with images) and it seems to work nicely. However, I'd like to make a version that scrolls right instead of left, but haven't been able to figure it out. I've tried changing ".append" to ".prepend" and playing with the margin changes, but no luck so far.
Any suggestions?
I forked and retooled your JSFiddle to make it scroll from left to right. Check it out here: https://jsfiddle.net/1jw8xpqe/
Had to change a few things to get it working. First, the list is parsed to reverse the order of the slides and shift a couple of them so the leftmost one is "Item #1" when the slider initializes:
// reverse items
var list = $('ul');
var listItems = list.children('li');
list.append(listItems.get().reverse());
// rearrange last two items so first slide starts on left
list.prepend($('ul li:last-child').prev('li').andSelf());
Then a few CSS/JS tweaks: The slide animates the first li from -200px (defined in the CSS) to 0, and after each cycle, prepends the last item of the ul to the start at -200px. Hope this helps!
I have a jQuery simple slider it has 15 picture each five show in a slide. I have a previous button and next button.
Each next click generate a left movement by 855px with a slider animation.
Each previous click generate a right movement by 855px with a slider animation.
This is my jQuery code :
$(document).ready(function(){
$(".prev_button").click(function(){
$("ul.slider").animate({
left: "+=855"
}, 3000, function(){
$("ul.slider").css('left', '0');
li_no = 0;
$("ul.slider").find("li").each(function(){
li_no = li_no + 1;
});
slide_after_this = li_no - 6;
$('ul.slider li:gt('+slide_after_this+')').prependTo('ul.slider'); // << line changed
});
});
$(".next_button").click(function(){
//alert($("ul.slider").css("right"));
$("ul.slider").animate({
right: "+=855"
}, 3000, function(){
//alert($("ul.slider").css("right"));
$("ul.slider").css('right', '0');
$('ul.slider li:not(:nth-child(n+6))').appendTo('ul.slider');
});
});
});
Now I have two problems :
First one is with the previous button (left arrow) When I click it the animation shows and the elements changed but they do not wrapped with each other (I mean does not show the last elements immidiatly before the first element). I can not find the reason of this.
Second problem is with both right and left arrows it is like following :
If I click just the right arrow the slider working fine it animates and change the elements but If I click the both button in order (I mean right then left or left then right ) the elements change but the animation does not show. but I check if the routine go inside the animate function by some alerts and it is going inside but does not animate on the screen .
This is a link that may help you:
http://jsfiddle.net/mpx83tpv/18/
you are really close try overflow:hidden for .slider_container
div.slider_container
{
height:380px;
width:855px;
margin-left:auto;
margin-right:auto;
overflow:hidden;
}
edit js:
also use below code as you are using both right and left in the end the slider has both of them one of them is always zero.
$(document).ready(function(){
$(".prev_button").click(function(){
$("ul.slider").animate({
left: "+=855"
}, 3000);
});
$(".next_button").click(function(){
//alert($("ul.slider").css("right"));
$("ul.slider").animate({
left: "-=855"
}, 3000);
});
});
if you want a infinite scrolling you need to use right and left in this case replace your $("ul.slider").css('right', '0'); line to $("ul.slider").css('right', ''); do same for left as well, as you need the remove them.
for adding the next visible div implement you logic before the animation as you callbacks do it after the animation.
the tricky part would be the prev button for this after calculation of the div count you also need the set new left without animation and then call left move animation.
hope these make sense.
I want the class .disabled to be added to the left and/or right controls (.tab-left, .tab-right) if the first or last tab is showing so a user can see that they have reached the end and cannot click any further.
Right now I something like this to prevent the user from going past the end.
if (tabs are at the end) {
return;
}
This works for users not being able to click past the end, but if I add the class before returning, the problem is the .disabled class won't be added until the tabs have reached the end and the user clicks again.
if (tabs are at the end) {
$('.tab-right').addClass('disabled');
return;
}
I need the disabled class to be added when the last tab is showing, not when the user trys to click past the end.
Here's a link to the js fiddle: http://jsfiddle.net/uue6pgcx/
One option you could try is to enable/disable the right and left buttons once the animation is complete.
$ul.filter(':not(:animated)').animate({
"left": dir + liWidth
}, {
complete: function () {
// Calculate the number of items in the container (without left and right navigation buttons).
var lisContainer = Math.round(($container.width() - $left.outerWidth() - $right.outerWidth()) / liWidth);
// Disable right button when list is moved to the left a number of items
// such as the remaining number of them is less or equal than the number
// of items that fit in the container.
$right.toggleClass('disabled', $li.length + $ul.position().left / liWidth <= lisContainer);
// Disable left button when list is in the origin.
$left.toggleClass('disabled', $ul.position().left === 0);
}
});
Disclaimer: According to jQuery outerWidth additional notes, The number returned by dimensions-related APIs, including .outerWidth(), may be fractional in some cases. Code should not assume it is an integer.. So lets hope Math.round will suffice to get the proper number.
Maybe there is a better way to calculate if the right button must be disabled/enabled instead of relying on the number of items that fit in the container.
Here it is your code with the above modification:
http://jsfiddle.net/0Lsepxeu/
I'm trying to add in previous and next buttons to my content slider but seem to be having problems, what I would really like to do is move the $slideCtn left or right by the width slideWidth each time the previous or next button is clicked but i'm unsure how to increment each click by the value of slideWidth. I've tried ++ and -- etc but with no results, would anyone be able to show me the best way to do something like this? Also any other advice very welcome!
Or should I create a global index variable that gets set at 0, then as the pagination x's are clicked or the prev/next arrows are clicked update this global variable?
JS Snippet
//Add previous + next arrows
$dirArrows.on('click', function(e){
var arrDir = $(this).data('dir');
$slideCtn.css('left', ( arrDir === 'prev' ) ? -(slideWidth) : +(slideWidth));
e.preventDefault();
});
JS Fiddle
http://jsfiddle.net/SG5ad/10/
At the moment, you're telling it to move to an absolute position - either -200px or +200px (never 0px, 400px, 600px, etc).
You'll need to take into account its current position as well as how much you want to adjust it: http://jsfiddle.net/SG5ad/12/
var arrDir = $(this).data('dir')
iLeft = parseInt( $slideCtn.css('left') );
$slideCtn.css('left', ( arrDir === 'prev' ) ? iLeft - slideWidth : iLeft + slideWidth);
A bug you'll want to fix as well is that the Next/Prev buttons do nothing until you've already jumped to a specific slide with the "x" navigation.
As an entirely separate issue, about 6 months ago I wrote something like this as part of a project at work (it had a few more bells and whistles, but nothing drastically different), and there's one important thing I'd say is worth changing.
In order to go from slide a to slide d at the moment, you animate slides a,b,c and d, which means that
a) 4 slides are animating instead of 1 (plus all their child elements)
b) you have to pass through slides b and c even though they're not relevant
I'd have a look at changing the base position of all your slides to be stacked on top of each other using z-index, then simply animating the top slide off to one side to reveal the one underneath it. It requires a bit of code to track which slides are where ($.data() may help there) but gives you a much more performant slider at the end of it.
You've gotta do it with .animate()
$dirArrows.on('click', function(e){
var arrDir = $(this).data('dir');
if (arrdir == left){
$slideCtn.animate({
left: "+=250"
});
}
});
So I previously asked a question about how to create a banner like the one shown here and I got a really good answer to start me off. I have been working on it since and I'm having a lot of problems getting the animation to slide back to it's original position.
Here is my animation: http://jsfiddle.net/43nCF/ (don't click the green block first)
Issue: After the first time you toggle a block, clicking another block will not move it to the left.
I also have some other minor issues which I would be grateful if someone helped me with.
How do I get the width and the moving of the blocks to animate simultaneously like in the banner animation I am trying to replicate?
How do I get the block to slide back to the original position instead of just kind of 'transporting' there?
I am only beginner at jQuery so any help would be amazing.Thanks.
As for the positioning problem: you need to drop the left declaration in your second function.
Regarding making the animation act simultanous: animate both the right and the width property for each element, in one call:
function() {
var position = $.data(this, 'position');
var ind = $(this).index();
//moves image back to original position
$('#container div').each(
function() {
$(this).animate({
right: "",
width: 100
});
});
});
Working example here.
I see you have a response.
In case this version is of any help to you:
http://jsfiddle.net/vCbcz/
Instead of altering the divs other than the one being affected, I wrapped them all in a #slider div and adjusted that one's left margin to push it to the left.
$('#slider').animate({
marginLeft: '-' + ind * 105 + 'px'
});
and back
$('#slider').animate({
marginLeft: 0 + 'px'
});
There is a much easier way altogether of doing this. By using jQuery's scrollTo plugin, this can be done in a mere few lines of code, without using indices, calculations, or anything of that nature.
Live Demo http://jsfiddle.net/Jaybles/WEzny/