Scroll down page event for x seconds - javascript

I am currently able to scroll down a page with the help of CasperJS. I saw this article on how to scroll infinite pages based on the visibility of certain attributes. However I don't want to base it on the visibility of an element but was wondering if there is a way to set a timer on how long it should stay scrolling down before exiting out. How would be able to such thing?
//function to scroll
function tryAndScroll(casper) {
casper.page.scrollPosition = {
top: casper.page.scrollPosition["top"] + 40000,
left: 0
};
}
/**
* Everything starts here!
* I use the mobile version of facebook as the DOM is waaay simpler to scrape.
*/
casper.start('https://www.somesite.com', function() {
});
casper.then(function() {
tryAndScroll(this);
});
casper.then(function() {;
this.exit();
});
casper.run();

Here's a simple way:
function tryAndScroll(casper) {
casper.page.scrollPosition = {
top: casper.page.scrollPosition["top"] + 300,
left: 0
};
}
casper.start(url).then(function() {
var self = this;
var intervalId = setInterval(function(){
tryAndScroll(self);
}, 100); // retry interval
self.wait(10000 /* infinite scroll timeout */, function(){
clearInterval(intervalId);
});
}).run();
Since setInterval() is not a CasperJS step function, this essentially break out of the control flow of CasperJS. The wait() is necessary so that CasperJS doesn't execute something else during the scroll.
Also, you can't use a scroll distance of 40000 pixels. This is too big and PhantomJS won't be able to take a screenshot.

Related

Scroll down to bottom. Then reload page and do it again

I'm using this simple code, and it's working fine.
$("#mydiv").animate({ scrollTop: $('#mydiv')[0].scrollHeight}, 20000)
What I would like is to after the bottom has been reached immediately go back to the top of the page and start scrolling down slowly again. How would one achive something like this in JQuery?
Thank you guys!
you can jump back to the top of your page using the following javascript function:
function jump(elementId){
var location = document.getElementById(elementId).offsetTop;
window.scrollTo(0, location);
}
just use the id of some element at the top of your page.
Not sure what you are trying to do and what "reload" means but here is a quick snippet to get you started:
JSnippet Demo
As you can see its configurable and easy to understand:
$(function() {
var pageScan = {
speed : 10000,
loop : true,
delayRestart : 1000,
start : function(){
pageHeight = $('body').height() - window.innerHeight;
pageScan.proc(pageHeight);
},
proc : function(to){
$("body").animate(
{scrollTop: to},
pageScan.speed,
"linear",
function(){
if (pageScan.loop) {
setTimeout(function() {
window.scrollTo(0, 0);
pageScan.start();
}, pageScan.delayRestart);
}
});
}
};
pageScan.start();
});
We could do something easier like this:
(function (){
var div = $('#myDiv'),
infiniteScroll = function () {
//---gets the bottom of the page value
var bottomHeight = div[0].scrollHeight;
var callback1 = function () {
//once it gets into this callback function
//it resets the position to zero
div.scrollTop(0);
//invokes again the function infinite scroll
infiniteScroll();
};
div.animate({scrollTop:bottomHeight},20000,callback1)
};
//starts the function for the very first time
infiniteScroll();
})();
I created a codepen so you can see it working and play with it:
http://codepen.io/dieggger/pen/VLoZWv?editors=101

Mobile Splash Page

I have a mobile site already, and what I want to do is add an image that shows up when you hit the page for 5 seconds. Once 5 seconds has passed it just disappears and you're at the homepage.
Is this possible for an android device? Is there a way to make the image display on the entire screen?
Thanks!
It's easier with jQuery. You can style a div to be your splash page and set a function to run when the page is loaded. After the 5 second duration, you can hide the div.
It could possibly look something like this:
$('div.introDiv').animate( {
opacity: 'toggle' // if div is hidden, it will fade in
},
{
duration: 5000, // in ms
complete: function () {
$('div.introDiv').animate(
{
opacity: 'toggle' // div will fade out
},
{
duration: 5000, // 5 seconds
complete:function () {
// hide div and show main content
}
})
}
}
);
This isn't the only way to do this, but it works.
Try something like...
<body onload="redirectMobile()">
var redirectMobile = function() {
setTimeout(function(){
window.location = 'http://www.google.com/';
},5000);
};
or skip the function and do...
<body onload="setTimeout(function(){window.location = 'http://www.google.com/'},5000)">
Like the previous answer said, jquery or another way might be easier, but this should work with pure javascript.

Delay animation until other animation is complete (sliding content(

I have this code which animates between divs sliding out. If an item is clicked, it's relevant content slides out. If another item is clicked, the current content slides back in and the new content slides out.
However,
var lastClicked = null;
var animateClasses = ['ale', 'bramling', 'bullet', 'miami-weisse'];
for (var i=0; i<animateClasses.length; i++) {
(function(animCls) {
$('.each-brew.'+animCls).toggle(function() {
if (lastClicked && lastClicked != this) {
// animate it back
$(lastClicked).trigger('click');
}
lastClicked = this;
$('.each-brew-content.'+animCls).show().animate({ left: '0' }, 1000).css('position','inherit');
}, function() {
$('.each-brew-content.'+animCls)
.animate({ left: '-33.3333%' }, 1000, function() { $(this).hide()}) // hide the element in the animation on-complete callback
.css('position','relative');
});
})(animateClasses[i]); // self calling anonymous function
}
However, the content sliding out once the already open content slides back is sliding out too quickly - it needs to wait until the content has fully slided back in before it slides out. Is this possible?
Here's a link to what I'm currently working on to get an idea (http://goo.gl/s8Tl6).
Cheers in advance,
R
Here's my take on it as a drop-in replacement with no markup changes. You want one of three things to happen when a menu item is clicked:
if the clicked item is currently showing, hide it
if something else is showing, hide it, then show the current item's content
if nothing is showing, show the current item's content
var lastClicked = null;
// here lastClicked points to the currently visible content
var animateClasses = ['ale', 'bramling', 'bullet', 'miami-weisse'];
for (var i=0; i<animateClasses.length; i++) {
(function(animCls) {
$('.each-brew.'+animCls).click(function(event){
if(lastClicked && lastClicked == animCls){
// if the lastClicked is `this` then just hide the content
$('.each-brew-content.'+animCls).animate(
{ left: '-33.3333%' }, 1000,
function() {
$(this).hide();
}).css('position','relative');
lastClicked = null;
}else{
if(lastClicked){
// if something else is lastClicked, hide it,
//then trigger a click on the new target
$('.each-brew-content.'+lastClicked).animate(
{ left: '-33.3333%' }, 1000,
function() {
$(this).hide();
$(event.target).trigger('click');
}).css('position','relative');
lastClicked = null;
}else{
// if there is no currently visible div,
// show our content
$('.each-brew-content.'+animCls).show()
.animate({ left: '0' }, 1000)
.css('position','relative');
lastClicked = animCls;
}
}
});
})(animateClasses[i]); // self calling anonymous function
}
Well, I'm pretty sure there are other more easy possibilities and I didn't have much time but here is a working jsfiddle: http://jsfiddle.net/uaNKz/
Basicly you use the callback function to wait until the animation is complete. In this special case it's the complete: function(){...}
$("document").ready(function(){
$('#ale').click(function(){
if ($('div').hasClass('toggled')){
$('.toggled').animate({ width: "toggle" }, { duration:250, complete: function(){
$('#alecont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');}
}).removeClass('toggled');
}else{
$('#alecont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');
}
});
$('#bramling').click(function(){
if ($('div').hasClass('toggled')){
$('.toggled').animate({ width: "toggle" }, { duration:250, complete: function(){
$('#bramcont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');}
}).removeClass('toggled');
}else{
$('#bramcont').animate({ width: "toggle" }, { duration:250 }).addClass('toggled');
}
});
});
I give a toggled class if a div is expanded. Since the animation on your page seems to be pretty much broken I think this would be a better way to do this. But remember: my code isn't really good. Just fast and it can be refactored. It's working tho..
Rather than using toggles, bind an on "click" handler to your ".each-brew" divs. In the handler, first hide content divs and then show the appropriate content when that animation completes. You can do that with either a promise or a callback. Something like this...
$(".each-brew").on("click", function (event) {
$(".each-brew-content").show().animate({ left: "0" }, 1000, function() {
// Get the brew name from the class list.
// This assumes that the brew is the second class in the list, as in your markup.
var brew = event.currentTarget.className.split(/\s+/)[1];
$(".each-brew-content." + brew).animate({ left: "-33.3333%" }, 1000, function() { $(this).hide(); });
});
});
I think an event and observer would do the trick for you.
set up the callback function on completion of your animation to fire an event.
the listener would first listen for any animation event and after that event is triggered listen for the completion event. when the completion event is fired execute the initial animation event.run method (or whatever you would want to call it)
Within the listener
on newanimationeventtriger(new_anim) wait for x seconds (to eliminate infinite loop poss) while if this lastevent triggers done == true{
new_anim.run();
}

Jquery Animate - trigger function mid way through animation

Is it possible to trigger a function mid way through an animation?
The animation includes a solid block which swipes over an image from top to bottom - I would like to trigger a function at the point that the image is completely covered and remove the image from the html (mid way through the animation)
My current function is -
function animateCover() {
$('#cover').animate({ bottom: '1400px'}, 4000, function() { });
}
The image is completely covered at 800px point - can I access this property to trigger a function?
since there isn't a tick counter in jQuery, you need to "emulate" it:
function animateCover() {
var
$cover = $('#cover'),
interval = setInterval(function(){
if ($cover.is(':animated')){
if (parseInt($cover.css('bottom')) > 800){
alert('trigger');
clearInterval(interval);
}
} else {
clearInterval(interval);
}
}, 13); // 13 is the minimum possible in Javascript
$cover.animate({ bottom: '1400px'}, 4000, function() { $cover.text('done'); });
}
jsFiddle: http://jsfiddle.net/emV4p/1/
What about splitting the animation into 2.
function animateCover() {
$('#cover').animate({ bottom: '700px'}, 2000, function() {
$('#imgID').hide();
$('#cover').animate({ bottom: '1400px'}, 2000 );
});
}
Updated: Here's a perfectly working solution with minimal code-
WORKING DEMO
jQuery-
$(document).ready(function(){
setInterval(function(){
$("#image").css('background-image','none');
},2000);
$("#block").animate({
bottom:'400px'
},3000);
});

jquery clickling fast

I have this function, that adds 31px to my style bottom on ul.
It works fine, but if I click fast, it no longer adds 31px, but some weird number like 17.423px. I guess it's because the animation isn't done, and thereby by clicking fast it adds 31px to the current px amount. My thought is that I need to insert a stop(). But where?
$(function () {
$('.topTenTwocolumns .topTenTwocolumnsWrap .down').click(function () {
if ($("ul").css("bottom") !== '2728px') {
$(this).parents('.topTenTwocolumnsWrap').children('ul').stop().animate({
bottom: '+=31'
}, 200);
}
});
});
The animations are queued, but it might be that the values to animate are calculated before the animation is queued, and as you are using a relative value it would calculate the animation from it current position.
You already have a stop call in the code. I don't know if you added that afterwards, otherwise that could also explain the values. If you stop the animation halfways, the bottom value will naturally be changed halfways.
You could keep the current target value in a variable so that you can specify an absolute value for the animation:
$(function () {
var current = 0;
$('.topTenTwocolumns .topTenTwocolumnsWrap .down').click(function () {
if (current < 2728) {
current += 31;
$(this).parents('.topTenTwocolumnsWrap').children('ul').stop().animate({
bottom: current + 'px'
}, 200);
}
});
});
This way you can keep the stop call so that the new animation replaces the previous instead of being queued.
I would probably try to prevent the function from firing if one is already in flight. Something like this might work:
$(function () {
$('.topTenTwocolumns .topTenTwocolumnsWrap .down').click(function () {
if ($(this).data('in_flight') === true){
return false;
} else {
if ($("ul").css("bottom") !== '2728px') {
$(this).data('in_flight', true);
$(this).parents('.topTenTwocolumnsWrap').children('ul').stop().animate({
bottom: '+=31'
}, 200);
$(this).data('in_flight', false);
}
}
});
});
A more complicated approach would be to count the clicks and queue them (triggering the next one after the current running function completes). You could use similar code to do this.

Categories