Jquery Cycle Slider - Quick Clicks Break Slider - javascript

I've created somewhat of a complicated slider with jquery Cycle. You can see it running perfectly here
However, when you click it a bunch of times (before the slide has finished its transition), it starts to go wacky and even hides the text..
Here is my code:
$('#dmzSlideHolder').cycle({
fx: 'uncover',
pager: '#slideNav',
timeout: '8000',
before: function() {
var dmzTitle = $('.dmzSlideTitle p', this).html() + '<span class="arrow">ยป</span>';
$('#slideTitle').stop().animate({width: 1}, 1000);
$('#slideTitle p').stop().html(dmzTitle).hide().delay(2000).slideDown();
},
after: function() {
var dmzTitle = $('.dmzSlideTitle', this);
$('#slideTitle').stop().animate({width: 575}, 1000);
},
});
Any ideas? I thought .stop() would remedy this, but it didnt..

Figured it out. Had to set the .slideUp and .slidedown to happen on the callback of .animate()

Related

jQuery animation. How to make it restart with every carousel slide

Below is the Jquery code being used to animate a few images, but i would like to remove the following line from the code
jQuery('.banner_underlay').removeAttr('style');
and then get the animation to replay with every carousel slide. My jquery code below. Can anyone help?
jQuery(document).ready(function () {
jQuery('.cycle-slideshow').cycle({
fx: 'scrollLeft',
after: on_after
});
});
function on_after()
{
jQuery('.banner_underlay').animate({
left: '+=1000',
}, 1050, function () {
jQuery('.banner_underlay').removeAttr('style');
});
jQuery('.banner_overlay').animate({
right: '+=2000',
}, 1050, function () {
jQuery('.banner_overlay').removeAttr('style');
});
}
Trigger/set up an event each time the carousel slides. Set up a listener to call on_after(), or whatever animation you want to restart, every time that event is triggered.

How do I properly delay jQuery animations when loading a remote HTML?

EDIT: This software package is the full and undoctored version of what I'm trying to fix here. The problem is in the /data/renderpage.js script. Feel free to examine this before continuing.
https://github.com/Tricorne-Games/HyperBook
I really appreciate all the help guys!
=
I am polishing a jQuery script to do the following in a rigid sequence...
Fade out the text.
Shrink the size of the container div.
Preload the remote HTML ///without showing it yet!///
Open the size of the container div.
Fade in the new remote HTML.
I do not mind if steps 1 and 2, 4 and 5 are combined to be one whole step (fade/resize at the same time). It's when the new HTML is loaded it interrupts the entire animation, even from the beginning.
The idea is that I do not want my remote HTML to show until after the animation renders right. I want the original text to fade out and the container div close up, then, behind the scenes, ready the text of the new HTML, and then have the container div open up and fade the new text in.
It seems when I call the load(url) function, it instantaneously loads the page up, and the animations are still running (like the new HTML ends up fading out, only to fade back in, and not the original text out and then the new one in). Either that, or the whole function is calling each line at the same time, and it's disrupting the page-changing effect I want.
Here's my current script setup...
$(document).ready(function() {
// Start-Up Page Load (Cover, ToC, etc.)
$('#content').load('pages/page1.htm');
// Navigating Pages
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
$('#content_container').animate({height: 'hide'}, 500);
$('#content').fadeTo('slow', 0.25);
$('#content').load(ahref);
$('#content').css({opacity: 0.0});
$('#content').fadeTo('slow', 1.0);
$('#content_container').animate({height: 'show'}, 500);
return false;
});
});
What is it wrong I'm doing here? I have used the delay() function on every one of those steps and it doesn't solve the problem of holding back the new text.
jQuery objects can provide a promise for their animation queues by calling .promise on the jQuery element.
You can wait on one or more of these to complete using $.when() and then perform other operations.
The following does a fade out and slide up in parallel with the load, then (only when the animations complete), slides it down then fades it in (in sequence):
$(document).on('click', 'a', function (e) {
e.preventDefault();
var ahref = $(this).attr('href')
var $container = $('#content_container');
var $content = $('#content');
// Slide up and fadeout at the same time
$container.animate({
height: 'hide'
}, 500);
$content.fadeOut();
// Load the content while fading out
$('#content').load(ahref, function () {
// Wait for the fade and slide to complete
$.when($container.promise(), $content.promise()).then(function () {
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/3/
The only issue with this version is that the load may complete faster than the fadeout/slideup and show the new data too early. In this case you want to not use load, but use get (so you have control over when to insert the new content):
// Load the content while fading out
$.get(ahref, function (data) {
// Wait for the fade and slide to complete
$.when($container.promise(), $content.promise()).then(function () {
$content.html(data);
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/4/
Notes:
return false from a click handler does the same as e.stopPropagation() and e.preventDefault(), so you usually only need one or the other.
I started with the JSFiddle from #Pete as no other sample was handy. Thanks Pete.
Update:
Based on the full code now posted, you are returning full pages (including header and body tags). If you change your code to .load(ahref + " #content" ) it will extract only the part you want. This conflicts with the second (better) example I provided which would need the pages returned to be partial pages (or extract the required part only).
Additional Update:
As $.get also returns a jQuery promise, you can simplify it further to:
$.when($.get(ahref), $container.promise(), $content.promise()).then(function (data) {
$content.html(data);
// Slide down and fadein (in sequence)
$container.animate({
height: 'show'
}, 500, function () {
$content.fadeTo('slow', 1.0);
});
});
The resolve values from each promise passed to $.when are passed to the then in order, so the first parameter passed will be the data from the $.get promise.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pffm1tnb/11/
The issue is because you're not waiting for the hide animations to finish before loading the content, or waiting for the content to load before starting the show animations. You need to use the callback parameters of the relevant methods. Try this:
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href'),
$content = $('#content'),
$contentContainer = $('#content_container');
$contentContainer.animate({ height: 'hide'}, 500);
$content.fadeTo('slow', 0.25, function() {
// animation completed, load content:
$content.load(ahref, function() {
// load completed, show content:
$content.css({ opacity: 0.0 }).fadeTo('slow', 1.0);
$contentContainer.animate({ height: 'show' }, 500);
});
});
});
Note that for the effect to work the most effectively on the UI you would need to perform the load() after the animation which takes the longest to complete has finished.
Instead of using the load() function, you can use the get() function and its callback paramater to save the HTML into a variable before actually putting it into the element with html().
After doing all the animations to fade out and close the old box (and maybe inside an animation-finished callback function) you'll want to use something like the following:
$.get(ahref, function(data) {
// JQuery animation before we want to see the text.
$('#content').html(data); // actually inserts HTML into element.
// JQuery animation to fade the text in.
});
Using a bunch of the code everyone posted here, I rewrote the segment I originally had to follow suit. This is now my working result.
$(document).ready(function() {
// Start-Up Page Load (Cover, ToC, etc.)
$('#content').load('pages/page1.htm');
// Navigating Pages
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
$('#content').fadeTo('slow', 0.0)
$('#content_container').animate({height: 'hide'}, 500, function(){
$('#content').load(ahref + '#content', function(){
$('#content_container').animate({height: 'show'}, 500, function(){
$('#content').fadeTo('slow', 1.0);
});
});
});
return false;
});
});
You can use deferred or callbacks function
$(document).on('click', 'a', function(e) {
e.preventDefault();
var ahref = $(this).attr('href');
var dfd1 = $.Deferred();
var dfd2 = $.Deferred();
var dfd3 = $.Deferred();
var dfd4 = $.Deferred();
$('#content_container').animate({height: 'hide'}, 500, function(){
dfd1.resolve();
});
dfd1.done(function() {
$('#content').fadeTo('slow', 0.25, function() {
dfd2.resolve();
});
});
dfd2.done(function() {
$('#content').load(ahref, function() {
$('#content').css({opacity: 0.0});
dfd3.resolve();
});
});
dfd3.done(function() {
$('#content').fadeTo('slow', 1.0, function() {
dfd4.resolve();
});
});
dfd4.done(function() {
$('#content_container').animate({height: 'show'}, 500);
});
return false;
});

Stop/reverse animation on mouse off (baraja jquery plugin)

I've implemented the baraja jquery plugin for a section on a 'web app' that I need to create.
Rather than the plugin spreading the cards on the click of a button, I've opted to alter the script and spread out the cards on hover. On the face of it this works but if you hover over the cards and back off quickly before the animation is finished the cards will stay open. And then when you hover over the 'deck' they close. I've created a codepen below to show this:
http://codepen.io/moy/pen/OPyGgw
I've tried using .stop(); but it doesn't seem to have an impact on the result. Can anyone help me with this?
Additionally I'd like the deck to be open on page load, then close after a second or 2. I tried this with $( document ).ready() including the baraja.fan call but that didn't trigger it - any ideas?
this one really tickled me ;) tried several things, but - as already told - the plugin doesn't expect to get the close animation call faster, then the opening animation will run.
so finally i build you the following.
- opening the fan, right at document ready
- created a timeout for the mouseleave, to wait for the opening animation duration, before closing it - you will have a 400ms delay when mouseleave the element, but it will close, even when you've been to fast...
$(document).ready(function () {
if ($("#baraja-el").length) {
var $el = $('#baraja-el');
baraja = $el.baraja();
}
//initial open
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
$('.baraja-container').addClass('open');
// navigation
$('#baraja-prev').on('click', function (event) {
baraja.previous();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1000") {
$(this).addClass('visited');
}
});
});
$('#baraja-next').on('click', function (event) {
baraja.next();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1010") {
$(this).addClass('visited');
}
});
});
$('.baraja-container').hover(function (event) {
if(!$(this).hasClass('open'))
{
$(this).addClass('open');
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
}
}, function (event) {
curBarCon = $(this);
setTimeout(function(){
curBarCon.removeClass('open');
baraja.close();
}, 400);
});
$('.baraja-container li').click(function () {
$(this).addClass('visited');
});
});
since i fiddled in your codepen, you should have the working version here: http://codepen.io/moy/pen/OPyGgw
but... it's really no perfect solution. i'd suggest to get another plugin or rework baraja to get callback functions, which would test if the animation is currently running and dequeue them if needed.
rgrds,
E

Update DIV contents with current jQuery Cycle slide

I'm having difficulties updating the contents of a DIV with the current slide of my jQuery Cycle slideshow.
Here is the slider function, it currently will output the current slide as an alert (and works).
$(function () {
$('#slideshow').cycle({
fx: 'none',
timeout: 1,
continuation: 1,
speed: 'fast',
before: function (curr, next, opts) {
alert("Current slide " + opts.currSlide);
}
});
The DIV is as follows:
<div id="test">Hello</div>
And the code I'm trying to use (to replace the end of the code above):
$(function (curr, next, opts) {
var test = document.getElementById("test");
test.innerHTML = opts.currSlide;
});
Any thoughts on why the DIV does not update with the current slide #?
Unfortunately, nothing happens. I'm still learning my way around JS, so any pointers are much appreciated! Thank you for your time.
That variable in opts object (opts.currSlide) is not defined outside of the cycle function/plugin
so you would have to pass it to the function
$(function () {
$('#slideshow').cycle({
fx: 'none',
timeout: 1,
continuation: 1,
speed: 'fast',
before: function (curr, next, opts) {
getCurrSlide(opts.currSlide);
}
});
}):
function getCurrSlide(curr){
$("#test").html(curr);
}
OK. I have made a fiddle and there are a few thing to note. First your action added to the initial cycle will be removed when you hit your buttons. Here I have made the initial cycle do what you want and have added a button that you might use to get a 'snapshot' Note the selector to get only the currently visible image.
the meat:
$('#slideshow').cycle({
fx: 'none',
timeout: 1,
continuation: 1,
speed: 'fast',
before: function (curr, next, opts) {
$('#testNum').html("Current slide " + opts.currSlide);
var $img = $("#slideshow img:visible").clone();
$("#test").html('').append($img); }
});
// The button will work after you click fast,slow, or reverse.
// The reason for that is the .cycle function above replaces it
// as fast as you can see it.
$("#btnCopy").on("click",function(){
var $img = $("#slideshow img:visible").clone();
$("#test").html('').append($img);
});

Fading Latest News Ticker

I'm looking to get the most efficient way to produce a latest news ticker.
I have a ul which can hold any number of li's and all I need to to loop through them fading one in, holding it for 5 seconds and then fading it out, one li at a time. The list is displaying with an li height of 40px and the well it displays in is also 40px which with overflow: hidden which produces the desired effect. Also to be able to hold the li in place if the cursor hovers over it while its being displayed would be great to build it.
I know there is the jQuery ticker plugin that is widely used (ala the old BBC style) but I've tried to use it and it seems so bulky for the simplicity I need and it plays havoc with the styling I use.
I've been using this so far:
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker')).css('opacity', 1); });
}
setInterval(function(){ tickOut () }, 5500);
But it doesn't actually fade in the next li so the effect is a bit messy.
If someone could suggest some alternations to help produce the effect I need that would be so useful.
Thanks
hide() and call fadein() the element after it becomes the top of the list.
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker'))
$('#ticker li:first').hide()
$('#ticker li:first').fadeIn(1000)
$('#ticker li:not(:first)').css('opacity', '1')
});
}
setInterval(function(){ tickOut () }, 5500);
see:
http://codepen.io/anon/pen/lHdGb
I woudl do it like that:
function tickOut(){
$('#ticker li:first').animate({'opacity':0}, 1000, function () {
$(this).appendTo($('#ticker')).css('opacity', 1); });
}
var interval;
$(function() {
interval = setInterval(function(){ tickOut () }, 5500);
$('#ticker').hover(function() {
if(interval)
clearInterval(interval);
$('#ticker li:first').stop();
$('#ticker li:first').css('opacity', 1).stop();
}, function(){
interval = setInterval(function(){ tickOut () }, 5500);
});
});
See $('#ticker').hover which clears interval and stops animation and returns opacity to 1 when mouse got inside UL (may be changed to do that when only some special element inside LI is under mouse) and starts it again once it left that UL. Demo: http://jsfiddle.net/KFyzq/6/

Categories

Resources