jQuery Cycle plugin: Unpredictable behaviour after current browser tab loses focus - javascript

We have developed a jQuery plugin based on the jQuery Easing and Cycle plugins. A sample can be seen at http://jsfiddle.net/Dx5N4/3/embedded/result/. The idea is to have multiple lists of items (say, images) to which the Cycle plugin is applied. Each list is given a different initial delay so that the jQuery Cycle slideshows on each list begin at a different point in time. A quick sample from the plugin is shown below.
var delay = 100;
$("#slideshow ul").each(function() {
$(this).cycle({ delay : delay
, easing : "easeInOutElastic"
, fx : "scrollUp" });
delay += 100;
});
When the page loads, the plugin works just fine. The Cycle plugin is applied correctly, the slideshows start and slides transition with a delay, as expected.
However, if the user switches to a different browser tab, minimizes the browser window or switches to a different application and then comes back to the browser tab with the slideshows, the delay between individual slideshows is lost. Completely unpredictable behaviour ensues at this point, ranging from all slideshows transitioning at the same time, to none transitioning at all.
Any thoughts on what goes wrong when the browser tab loses focus, and how this can be corrected?

Modified the plugin to trigger slide transitions manually through normal JavaScript.
var slideshows = $("ul", $("#slideshow"));
$(slideshows).each(function() {
$(this).cycle({ easing : "easeOutElastic", fx : "scrollUp", timeout : 0 });
});
setInterval(function() {
var item = 1;
slideshows.each(function() {
var slideshow = $(this);
setTimeout(function() {
slideshow.cycle("next");
}, item++ * 100);
});
}, 4000);
The modified (working) code is available at http://jsfiddle.net/Dx5N4/5/embedded/result/.

Related

How to apply animations on two elements at once with animated.css

I am working on a simple slideshow where each slide has its own duration.
I would like to add transitions between the slides using animate.css by adding and removing classes on the current and the next slides.
My problem is that - with my current approach - only the next slide will be animated (it slides in) but the current one is just disappear without any animation.
I have tried to detect the end of the current animation and then change(adding/removing) the classes but in that case there was a huge gap between the slides...
How can make sure that two animations plays at once?`
var slides = $this.find('.slide');
slideIt = function(time) {
setTimeout(function() {
var duration = slides.eq(nextSlide).data('duration');
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut)
.hide();
slides.eq(nextSlide)
.removeClass(animateOut)
.addClass(animateIn)
.show();
slideIt(duration);
currentSlide = nextSlide; nextSlide ++;
if (nextSlide == slidesLength) { nextSlide = 0;}
},time);
};
Thank you for the help in advance!
Ps.: While typing this post I have realized that it must be the .hide() but without it only the first slide displayed.
Native CSS animations on two different elements should always run at the same time.
But if you hide an element, it disappears before the animation has even started. You have to add a timer for that.
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut);
// save the jQuery instance of the element that should be hidden.
var $currentSlide = slides.eq(currentSlide);
// hide this element later
setTimeout(function() {
$currentSlide.hide();
}, 1000); // 1000 for 1000ms, replace that with the duration of the animateOut animation
If my first answer doesn't satisfy you, because you want so solve that on the CSS side, when there is a second way:
Remove the .hide() in JavaScript.
Make sure your CSS animation ends with a state, there the element cannot be seen anymore (like transform: scale(0) or left: -100%).
Maintain that final state of the CSS animation. To do that, see: Maintaining the final state at end of a CSS3 animation

Clipping path transition between sections with fullPage.js

I would like to have a clipping animation with the SVG clipping path that would hide the first section and show the second while animating using fullPage.js.
So this is similar to this question:
fullpage JS animation on section
yet I would like to have controlled animation with specific duration (so the transition is smooth).
What I know or have tried now:
FullPage.js onLeave and afterLoad callbacks will have to be used. If I prevent scrolling in onLeave event I can call silentMoveTo only in afterLoad event yet I need what's in the next two points.
Two sections cannot be active (CSS class) with fullPage.js (so for example I would change the section 2 opacity from 0 to 1 as the animation reveals it, while section 1 would be hidden vice versa and the background clipping path would move to top to hide the section 1 image (SVG).
I've tried to animate the clipping path (have similar working example) yet of course the content of the section 2 below is not displayed. Calling silentMoveTo to show section 2 after the animation is not usable so it will have to be synchronized with say 50% of animation duration passed.
What would be the best approach? I have to use fullPage.js (by request, built in WordPress theme used). Ideally I plan to use a timeline in GreenSock javascript library with a callback on animation end to properly signalize fullPage.js main object that active section should now be #2.
ADDED: you can see one approach of using transitions with GreenSock here:
https://youtu.be/gE-Yuu2eEio?t=1694
yet this is the animation AFTER the second section loads. I want to have an animation of the first section contents that at the same time reveals the second section (I am aware of Fading Effect fullPage.js extension, not the solution to this).
So I guess I have to answer this myself.
Short answer: it's not possible to show two sections at the same time using fullPage.js as (it is) designed.
Long answer: you can at least mimick some kind of interaction e.g. longer animation during first section and then quickly show the second one. Like this (you cannot run this code due to removing unnecessary parts for discussion):
var fullPageOBj = new $('#fullpage').fullpage({
...
onLeave: function (origin, destination, direction) {
dir = direction;
...
if(origin == 1 && destination == 2){
$.fn.fullpage.setAutoScrolling(false);
document.body.style.overflow = "hidden";
...
TweenMax.to(bSvg, 2.7, { }, "section1");
...
}
$.fn.fullpage && $.fn.fullpage.setLockAnchors && $.fn.fullpage.setLockAnchors('false');
},
afterLoad: function (origin, destination) {
console.log("aL - origin: " + origin + ", destination: " + destination + ", direction: " + dir);
if(destination == 1){
$("vc-section1").addClass("active");
...
}
if(destination == 2){
TweenMax.to(bSvg, 0, { display: "block", onComplete: Delay2, delay: 3.2});
function Delay2() {
$.fn.fullpage.setAutoScrolling(true);
$.fn.fullpage.silentMoveTo(2);
}
}
}
}
The idea above is that the afterLoad event in fullPage.js is spawned practically immediately after onLeave event so you have to make sure to wait for animation in onLeave event function completes before afterLoad functions take place. So the above code includes spawning the Delay2 function that runs after an animation completes. The timing in afterLoad function is set to respect the time for an animation duration in onLeave function.
You'll have to play with the timings. Default transition time before sections in fullPage.js appears to be 700 ms.
The last idea would probably be to move animation to Section 2 - but the page is already without objects in Section 1 (to animate in transition to Section 2).
You're welcome to add to discussion.

Slide old page out as current page slides in

I'm using jquery on a single page web site to slide the next "page" onto the screen when the user clicks a button. I would like the current page to slide out to the left as the new page slides in from the right, so that there is no empty space shown, but currently I am only able to get the current page to disappear as the next page slides in. The code I'm using is here: http://jsfiddle.net/xoa029jz/5/
function slideToNext() {
var currentPage = $('.current-page');
var nextPage = getNextPage(currentPage.attr('id'));
$(nextPage).css('display', 'block');
$(currentPage).animate({left: '-100%'});
$(currentPage).removeClass('current-page');
$(nextPage).addClass('current-page');
$(nextPage).animate({left: '0%'});
}
Your CSS transitions are fighting with the jQuery animation. Until I hear which you prefer I have turned off the CSS transition.
The other fixes are to set the initial position of the elements about to animate and to wait for the panel to leave completely before removing the current-page class.
JSFiddle: http://jsfiddle.net/TrueBlueAussie/xoa029jz/8/
function slideToNext() {
var currentPage = $('.current-page');
var nextPage = getNextPage(currentPage.attr('id'));
currentPage.css('left', '0%').animate({
left: '-100%'
}, function () {
currentPage.removeClass('current-page');
});
nextPage.css({'display': 'block', 'left': '100%'}).addClass('current-page').animate({
left: '0%'
});
}
I also cleaned up a few redundant items (chained selectors etc).
You are better off just using jQuery animation, initially while you get it working, then adding a plugin (like velocity.js) to make the animations use CSS transitions, rather than try to mix the two.

Masonry and Infinite Scroll breaking layout when scrolling at certain speed

I have a fluid width theme and I am using jQuery Masonry and Infinite Scroll. The Problem is that if you scroll at a certain speed (not too fast and not too slow) the page it can cause a break in the grid. I have only seen this with two columns and in Firefox:
Anyone know why this is happening? I know it could be a number of things but if anyone has had experience with this and knows what is going on it would help greatly.
UPDATE:
The break happens right after the last post on the page. The ones that come after are being generated by infinite scroll's callback.
Well, I can not see the link to your page to look at (and the image is not available) but from my past experiences with masonry, whenever there is a major change in the page size (re-sizing, scrolling, re-sized divs) you need to trigger it again:
jQuery(document).ready(function() {
jQuery("#somediv").click(function() {
jQuery('#leftcol').toggle(700); //div resizing start here
jQuery('#somediv2').toggleClass("minside");
jQuery('#somediv').toggleClass("full"); // evoke again after change..
jQuery('#container').masonry({
itemSelector : '.item',
columnWidth : 240
});
});
});
Add this as callback for infinite scrolls and your problem will be gone... at least works for me:
// trigger Masonry as a callback
function (newElements) {
// hide new items while they are loading
var $newElems = $(newElements).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function () {
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry('appended', $newElems, true);
});
});
Check the $container just in case you've changed it.

jQuery div autoscroll

I am looking for advice on how to create an autoscrolling effect using jQuery which would enable an entire div within a page to begin scrolling vertically upon loading at a constant slow speed. This would be a div with a large amount of content of which only a small amount was visible on the screen at any one time.
The scroll needs to be automatic, smooth and at a defined rate for example 10 pixels per second. Additionally when the scroll gets to the bottom of the page I need to be able to call a function.
I have tried a few different jQuery plugins but found nothing yet that worked reliably. Can anybody suggest an approach to take here?
Thanks
Simon
This can easily be done without jquery.
function init() {
var div = document.getElementById("myDiv");
// increase the scroll position by 10 px every 10th of a second
setInterval(function() {
// make sure it's not at the bottom
if (div.scrollTop < div.scrollHeight - div.clientHeight)
div.scrollTop += 10; // move down
}, 100); // 100 milliseconds
}
Try this technique
try this plugin : scrollTo
especially the onAfter

Categories