I have created a basic carousel type slidshow, however to get it to work I had to call the following function twice for it to actually set the margin-left property to 0px.
$("#slide ul").stop().css('marginLeft', '0px');
I was wondering what I'm doing wrong, as I'm new to jquery.
The entire thing can be found here http://jsfiddle.net/xZBZK/
Just the JavaScript for convenience:
var offset = 0;
var count;
var width = 500;
var height = 333;
var interval;
$(document).ready(function() {
count = $("#slide ul").children().length;
// Add the first image to the end so it loops.
$("#slide ul").children().first().clone().appendTo("#slide ul");
start();
});
function nextImage() {
$("#slide ul").stop();
offset+=width;
if(offset / width == count) {
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700, 'linear', resetImage);
}
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700);
return offset;
}
function resetImage() {
$("#slide ul").stop().css('marginLeft', '0px');
$("#slide ul").stop().css('marginLeft', '0px');
offset = 0;
//start();
}
function stop() {
clearInterval(interval);
}
function start() {
interval = setInterval(nextImage, 3000);
}
I'm using JQuery 1.9.1
Is it because you are loading two animations into the queue?
if(offset / width == count) {
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700, 'linear', resetImage);
}
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700);
Maybe you want:
if(offset / width == count) {
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700, 'linear', resetImage);
}else{
$("#slide ul").animate({'marginLeft':'-'+offset+'px'}, 700);
}
I think .stop() only stops the current animation and doesn't clear the queue. so its defaulting to the animation before it.
Related
I am having a view problems with animating a background to give the impression that a window is opening, I have the animation actually animating but it just animates like the images are in sequence. What I am wanting is to give the impression of a movie or animated gif.
You can see my current attempt here,
http://jsfiddle.net/8nj4934w/
I have so far done the following javascript,
$('a').bind('mouseenter', function() {
var self = $(this);
this.iid = setInterval(function() {
self.animate({ 'background-position-y': '-=500px' });
}, 300);
}).bind('mouseleave', function(){
this.iid && clearInterval(this.iid);
});
and the kind of effect I am going for here,
http://www.jeld-wen.com/catalog/exterior-doors
just hover of a door image.
Update (for jQuery solution handling two way sliding)
function slide(that, increment, limit){
var self = $(that);
that.iid && clearInterval( that.iid );
that.pos = that.pos || 0;
return setInterval(function () {
that.pos = that.pos += increment;
if (that.pos === limit){
clearInterval(that.iid);
} else {
self.css({
'background-position': '0 '+ that.pos + 'px'
});
}
}, 50);
}
$('a').bind('mouseenter', function () {
this.iid = slide( this, -500, -11500 );
}).bind('mouseleave', function () {
this.iid = slide(this, 500, 0);
});
Demo at http://jsfiddle.net/g8cypadx/
Original answer
I would suggest that you use CSS transitions with steps.
a {
background-image: url('https://dl.dropboxusercontent.com/u/58586640/9100_FRONT_STRIP.png');
background-repeat: no-repeat;
height: 500px;
width: 500px;
display: block;
background-position: 0 0;
transition: background-position 1s steps(23);
}
a:hover {
background-position: 0 -11500px; /* number of steps times the height */
}
If you have to do it through jQuery then you should animate both properties but with 0 duration for the animation, and small delay for the interval
$('a').bind('mouseenter', function () {
var self = $(this);
this.iid = setInterval(function () {
self.animate({
'background-position': '-=0 -=500px'
}, 0);
}, 50);
}).bind('mouseleave', function () {
this.iid && clearInterval(this.iid);
});
Demo at http://jsfiddle.net/8nj4934w/2/
(the problem with this solution is that it will not stop at the end)
Currently working on an image carousel and I believe it is 99% done, except for one thing... I can only move one picture at a time, and then I have to rehover in order to keep the slider going. So is there some sort of jump statement or goto statement that I can use to continually run the loops?
Here is what I have so far :
Fiddle
JQuery
$(document).ready(function(){
$('.carousel').each(function(){
if($(this).width() < $(this).children('ul').width()){
$(this).children('carrow').each(function(){
$(this).hide();
});
}
});
$('.carousel').hover(function(){
$(this).children('.carrow').each(function(){
$(this).addClass('carrow-hover');
});
}, function(){
$(this).children('.carrow').each(function(){
$(this).removeClass('carrow-hover');
});
});
$('.carrow').hover(function(){
var SD = 210;
var $carousel = $(this).parent();
var $ul = $carousel.children('ul');
var distance = SD;
var time = 2500;
var rate = distance/time;
//When animation is completed, Jump back to here
distance = Math.abs($ul.position().left);
if($(this).hasClass('left-arrow')){
if(distance == 0) {
$ul.css({left: -210});
$ul.prepend($ul.children('li:last-child'));
} else {
time = distance/rate;
}
$ul.stop().animate({
left: 0
}, time, 'linear');
}
else if($(this).hasClass('right-arrow')){
if(distance != 0){
distance = SD - distance;
time = distance/rate;
}
$ul.stop().animate({
left: -210
}, time, 'linear', function(){
$ul.append($ul.children('li:first-child'));
$ul.css({left: 0});
});
}
}, function(){
$(this).parent().children('ul').stop();
});
});
You can separate animation routine in it's own function, e.g.
function myAnimate(that){
// animation goes here
}
And call itself as a callback function at the animation end
$ul.stop().animate({
left: 0
}, time, 'linear', function(){myAnimate(that)});
This way as soon as one animation ends - the other begins
Demo: http://jsfiddle.net/bjyuA/1/
All I did was loop the part I had wanted and created a few extra dependencies which Yuriy had fixed, but I figured I would share my approach as well.
$('.carrow').hover(function(){
var SD = 210;
var $this = $(this);
var $carousel = $(this).parent();
var $ul = $carousel.children('ul');
var distance = SD;
var time = 2500;
var rate = distance/time;
distance = Math.abs($ul.position().left);
continue_scroll = function(dist) {
time = 2500;
if(arguments.length != 0){
distance = dist;
}
if($this.hasClass('left-arrow')){
if(distance == 0) {
time = 2500;
} else {
time = distance/rate;
}
$ul.stop().animate({
left: 0
}, time, 'linear', function(){
$ul.prepend($ul.children('li:last-child'));
$ul.css({left: -210});
continue_scroll(210);
});
}
else if($this.hasClass('right-arrow')){
if(distance != 0 && arguments.length == 0){
distance = SD - distance;
time = distance/rate;
}
$ul.stop().animate({
left: -210
}, time, 'linear', function(){
$ul.append($ul.children('li:first-child'));
$ul.css({left: 0});
continue_scroll(0);
});
}
}
continue_scroll();
}, function(){
$(this).parent().children('ul').stop();
});
My function works 100% when i only scroll a little bit, but when i scroll all the page down and scroll up fast, my opacity:0 take longer or doesn't work at all. Have any idea why ? It is because my function i call to many times ?
$(window).scroll(function () {
var TopValue = $(window).scrollTop();
if (TopValue <= 50) {
$("div.mouseover > p").css('opacity', 0);
} else {
$("div.mouseover > p").animate({
opacity: '1.0'
}, 1000);
}
});
Since your function call is happening multiple times, You have to clear the animation queue before starting another animation, Please read .stop() for further clarifications.
Try this,
$(window).scroll(function () {
var TopValue = $(window).scrollTop();
if (TopValue <= 50) {
$("div.mouseover > p").css('opacity', 0);
} else {
$("div.mouseover > p").stop().animate({
opacity: '1.0'
}, 1000);
}
});
this is my first post,
I was looking for a solution to my problem, i have a jquery slider working at http://www.creo.com.uy/web/mytho/ which i want to make in automatic rotation.
The problem is: i need to set the slider in an automatic rotation. So would be, both options, clicking the arrows, and auto-slide.
The original code didn't come with that, even the guy who developed this theme, told me they didn't added that function.
So with a friend that understands javascript, we worked over the .js file to add some code, but we're missing something, cus in the last image, it gets in a recursive loop, from 4 to 3, from 3 to 4, and so on.
I deliver here both files, the original one, and the modified one, i hope you can help me with this!
Original:
jQuery(document).ready(function($) {
"use strict";
//prev = top
//current = middle
//next = bottom
var windowHeight = $(window).height();
$('.slide:first-child').addClass('current');
$('.slide:nth-child(2)').addClass('next').css('top', windowHeight);
$(window).resize(function() {
windowHeight = $(window).height();
$('.slide.next').css('top', windowHeight);
$('.slide.prev').css('top', -windowHeight);
});
if (!$('.slide.current').next('.slide').length) { $('#next').hide(); }
if (!$('.slide.current').prev('.slide').length) { $('#prev').hide(); }
function nextSlide() {
var current = $('.slide.current'),
next = current.next('.slide'),
prev = current.prev('.slide');
if (next.length) {
current.animate({
top: -windowHeight
}, 300);
next.animate({
top: 0
}, 300);
prev.removeClass('prev');
current.removeClass('current').addClass('prev');
next.removeClass('next').addClass('current');
next.next('.slide').addClass('next').css('top', windowHeight);
if (!$('.slide.current').next('.slide').length) {
$('#next').hide();
$('#prev').show();
} else {
$('#next').show();
}
}
}
function prevSlide() {
var current = $('.slide.current'),
next = current.next('.slide'),
prev = current.prev('.slide');
if (prev.length) {
current.animate({
top: windowHeight
}, 300);
prev.animate({
top: 0
}, 300);
next.removeClass('next');
current.removeClass('current').addClass('next');
prev.removeClass('prev').addClass('current');
prev.prev('.slide').addClass('prev').css('top', -windowHeight);
if (!$('.slide.current').prev('.slide').length) {
$('#prev').hide();
$('#next').show();
} else {
$('#prev').show();
}
}
}
$('#next').live('click', function() {
nextSlide();
return false;
});
$('#prev').live('click', function() {
prevSlide();
return false;
});
//Add swipe capabilities
$(".slide").swipe( {
swipeUp:function(event, direction, distance, duration, fingerCount) {
nextSlide();
},
swipeDown:function(event, direction, distance, duration, fingerCount) {
prevSlide();
},
//Default is 75px, set to 0 for demo so any distance triggers swipe
threshold:0
});
});
Modded:
jQuery(document).ready(function($) {
"use strict";
//prev = top
//current = middle
//next = bottom
var windowHeight = $(window).height();
var timeSlider = 3000;
var move = setTimeout(autoSlider,timeSlider);
function autoSlider(){
if (!$('.slide.current').next('.slide').length) {
prevSlide();
}else{
nextSlide();
}
}
$('.slide:first-child').addClass('current');
$('.slide:nth-child(2)').addClass('next').css('top', windowHeight);
$(window).resize(function() {
windowHeight = $(window).height();
$('.slide.next').css('top', windowHeight);
$('.slide.prev').css('top', -windowHeight);
});
if (!$('.slide.current').next('.slide').length){
$('#next').hide();
}
if (!$('.slide.current').prev('.slide').length){
$('#prev').hide();
}
function nextSlide() {
var current = $('.slide.current'),
next = current.next('.slide'),
prev = current.prev('.slide');
if (next.length) {
current.animate({
top: -windowHeight
}, 300);
next.animate({
top: 0
}, 300);
prev.removeClass('prev');
current.removeClass('current').addClass('prev');
next.removeClass('next').addClass('current');
next.next('.slide').addClass('next').css('top', windowHeight);
if (!$('.slide.current').next('.slide').length) {
$('#next').hide();
$('#prev').show();
} else {
$('#next').show();
}
}
clearTimeout(move);
move = setTimeout(autoSlider,timeSlider);
}
function prevSlide() {
var current = $('.slide.current'),
next = current.next('.slide'),
prev = current.prev('.slide');
if (prev.length) {
current.animate({
top: windowHeight
}, 300);
prev.animate({
top: 0
}, 300);
next.removeClass('next');
current.removeClass('current').addClass('next');
prev.removeClass('prev').addClass('current');
prev.prev('.slide').addClass('prev').css('top', -windowHeight);
if (!$('.slide.current').prev('.slide').length) {
$('#prev').hide();
$('#next').show();
} else {
$('#prev').show();
}
}
clearTimeout(move);
move = setTimeout(autoSlider,timeSlider);
}
$('#next').live('click', function() {
nextSlide();
return false;
});
$('#prev').live('click', function() {
prevSlide();
return false;
});
//Add swipe capabilities
$(".slide").swipe( {
swipeUp:function(event, direction, distance, duration, fingerCount) {
nextSlide();
},
swipeDown:function(event, direction, distance, duration, fingerCount) {
prevSlide();
},
//Default is 75px, set to 0 for demo so any distance triggers swipe
threshold:0
});
});
Thank you very very much in advance!
Nacho.
I have built a toggle that will slide down a div to reveal content. I am not using the normal toggle() function of jQuery because I wanted to show the top 300px of content and then slide to reveal the rest.
Anyways, I have a script setup that animates the height of the container div, which reveals the content inside.
function slideCut() {
var revertHeight = 300;
var finalHeight = 0;
var s = 1000;
$('.cutBottom a').click(function() {
event.stopPropagation();
var p = $(this).parent().parent();
var h = p.css('height', 'auto').height();
var cut = $(this).parent().find('.cutRepeat');
// Fix height
if (finalHeight == 0) {
p.css('height', 'auto');
finalHeight = p.height();
p.height(revertHeight);
}
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
p.animate({height:revertHeight}, {
duration: s
});
cut.fadeIn('fast');
} else {
$(this).addClass('toggled');
p.animate({height:finalHeight}, {
duration: s,
complete: function() {
cut.fadeOut('fast');
}
});
}
return false;
});
}//end
The problem is, the second time it animates the height to the full size (sliding the div to reveal content) it does not animate, it just jumps to the full height. Why is this happening?
Working example: http://jsfiddle.net/6xp2Y/3/
After all that hard work and fiddle being broken, all we had to do was remove one line from your code:
function slideCut() {
var revertHeight = 300;
var finalHeight = 0;
var s = 1000;
$('.cutBottom a').click(function() {
event.stopPropagation();
var p = $(this).parent().parent();
//var h = p.css('height', 'auto').height(); //REMOVE THIS LINE
var cut = $(this).parent().find('.cutRepeat');
// Fix height
if (finalHeight == 0) {
p.css('height', 'auto');
finalHeight = p.height();
p.height(revertHeight);
}
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
p.animate({height:revertHeight}, {
duration: s
});
cut.fadeIn('fast');
} else {
$(this).addClass('toggled');
p.animate({height:finalHeight}, {
duration: s,
complete: function() {
cut.fadeOut('fast');
}
});
}
return false;
});
}//end
slideCut();
Updated your fiddle: http://jsfiddle.net/brandonscript/6xp2Y/5/
Updated answer!
The proplem lies here
if (finalHeight == 0) {
parent.css('height', 'auto');
finalHeight = parent.height();
parent.height(revertHeight);
console.log('finalHeight:'+finalHeight);
}
This is only running at the beginning, because finalHeight is not 0 anymore after first run.
You can fix this by setting finalHeight back to 0 after closing it again, like so
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
parent.animate({height:revertHeight}, {
duration: speed
});
cut.fadeIn('fast');
finalHeight = 0;
} else { [...]