Continuous/Infinite scrolling - javascript

I have looked for a plugin/script that continues to scroll a website from the start when the bottom is reached, like a continuous loop.
Examples: http://unfold.no/ and http://www.aquiesdonde.com.ar/
I have tried reversed engineering but have not gotten to a conclusion.
Can anyone lead me in the right direction what to look for to find a plugin like this?
I only tend to find scripts that are continuously expanding the page/adding content on scroll-down.

It is just a if statement that tells the document if at x amount of pixels go to top y.
The code from: http://www.aquiesdonde.com.ar/
/*Scroll*/
var mov = 0;
function handle(delta) {
/*Scroll Action*/
if (delta < 0){
if(mov==-10500){
mov=0;
moverDown();
}else{
moverDown();
}
}else{
if(mov==0){
mov=-10440;
moverUp();
}else{
moverUp();
}
}
};
Plus the moverUp/moverDown functions which make the scrolling seamless:
/*Scroll Top*/
function moverUp(){
$('.layout').css( "top", mov+=30 );
};
/*Scroll Down*/
function moverDown(){
$('.layout').css( "top", mov-=30 );
};
/*Function Scroll*/
function wheel(event){
var delta = 0;
if (!event) event = window.event;
if (event.wheelDelta) {
delta = event.wheelDelta/120;
if (window.opera) delta = -delta;
} else if (event.detail) {
delta = -event.detail/3;
}
if (delta)
handle(delta);
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
};
Hope that helps.

Try using this script: https://github.com/paulirish/infinite-scroll
This is what you want to achieve written in JS using JQuery framework.

Related

jQuery "Snap To" Effect

I have a specific effect I want for a website I'm building. As you can see in this website, I want the screen to "snap to" the next section after the user scrolls, but only after (not the instant) the scroll event has fired. The reason I don't want to use a plugin like panelSnap is because I
1: Want smaller code and
2. Want the website, when viewed on mobile, to have more of the "instant snap" effect (try reducing the browser size in the website mentioned above). I know I theoretically could try combining two plugins, like panelsnap and scrollify, and activate them appropriately when the browser is a certain width, but I don't know if I want to do that... :(
So all of that said, here's the code:
var scrollTimeout = null;
var currentElem = 0;
var options = {
scrollSpeed: 1100,
selector: 'div.panels',
scrollDelay: 500,
};
$(document).ready(function() {
var $snapElems = $(options.selector);
console.log($($snapElems[currentElem]).offset().top);
function snap() {
if ($('html, body').scrollTop() >= $($snapElems[currentElem]).offset().top) {
if (currentElem < $snapElems.length-1) {
currentElem++;
}
}else{
if (currentElem > 0) {
currentElem = currentElem - 1;
}
}
$('html, body').animate({
scrollTop: $($snapElems[currentElem]).offset().top
}, options.scrollSpeed);
}
$(window).scroll(function() {
if ($(window).innerWidth() > 766) {
if (scrollTimeout) {clearTimeout(scrollTimeout);}
scrollTimeout = setTimeout(function(){snap()}, options.scrollDelay);
}else{
//I'll deal with this later
}
});
});
My problem is that every time the snap function is called, it triggers the scroll event, which throws it into a loop where the window won't stop scrolling between the first and second elements. Here's the poor, dysfunctional site: https://tcfchurch.herokuapp.com/index.html Thank for the help.
You can use a boolean to record when the scroll animation in snap is in progress and prevent your $(window).scroll() event handler from taking any action.
Here's a working example:
var scrollTimeout = null;
var currentElem = 0;
var options = {
scrollSpeed: 1100,
selector: 'div.panels',
scrollDelay: 500,
};
$(document).ready(function() {
var scrollInProgress = false;
var $snapElems = $(options.selector);
console.log($($snapElems[currentElem]).offset().top);
function snap() {
if ($('html, body').scrollTop() >= $($snapElems[currentElem]).offset().top) {
if (currentElem < $snapElems.length-1) {
currentElem++;
}
}else{
if (currentElem > 0) {
currentElem = currentElem - 1;
}
}
scrollInProgress = true;
$('html, body').animate({
scrollTop: $($snapElems[currentElem]).offset().top
}, options.scrollSpeed, 'swing', function() {
// this function is invoked when the scroll animate is complete
scrollInProgress = false;
});
}
$(window).scroll(function() {
if (scrollInProgress == false) {
if ($(window).innerWidth() > 766) {
if (scrollTimeout) {clearTimeout(scrollTimeout);}
scrollTimeout = setTimeout(function(){snap()}, options.scrollDelay);
}else{
//I'll deal with this later
}
}
});
});
The variable scrollInProgress is set to false by default. It is then set to true when the scroll animate starts. When the animate finishes, scrollInProgress is set back to false. A simple if statement at the top of your $(window).scroll() event handler prevents the handler from taking any action while the animate scroll is in progress.
Have you considered using the well known fullPage.js library for that? Check out this normal scroll example. The snap timeout is configurable through the option fitToSectionDelay.
And nothing to worry about the size... it is 7Kb Gzipped!
I know I theoretically could try combining two plugins, like panelsnap and scrollify, and activate them appropriately when the browser is a certain width, but I don't know if I want to do that
fullPage.js also provides responsiveWidth and responsiveHeight options to turn it off under certain dimensions.

jQuery mouse scroll script speed will not change

had a google....
Tried changing my website scroll settings & nothing is happening.
Anyone have a write up or table on mouse scroll jQuery scripts and functions?
(Caches were cleared, cross browser test etc.)
jQuery(window).load(function(){
if(checkBrowser() == 'Google Chrome' && device.windows()){
if (window.addEventListener) window.addEventListener('DOMMouseScroll', wheel, false);
window.onmousewheel = document.onmousewheel = wheel;
var time = 330;
var distance = 300;
function wheel(event) {
if (event.wheelDelta) delta = event.wheelDelta / 90;
else if (event.detail) delta = -event.detail / 3;
handle();
if (event.preventDefault) event.preventDefault();
event.returnValue = false;
}
function handle() {
jQuery('html, body').stop().animate({
scrollTop: jQuery(window).scrollTop() - (distance * delta)
}, time);
}
}
});
function checkBrowser(){
var ua = navigator.userAgent;
if (ua.search(/MSIE/) > 0) return 'Internet Explorer';
if (ua.search(/Firefox/) > 0) return 'Firefox';
if (ua.search(/Opera/) > 0) return 'Opera';
if (ua.search(/Chrome/) > 0) return 'Google Chrome';
if (ua.search(/Safari/) > 0) return 'Safari';
if (ua.search(/Konqueror/) > 0) return 'Konqueror';
if (ua.search(/Iceweasel/) > 0) return 'Debian Iceweasel';
if (ua.search(/SeaMonkey/) > 0) return 'SeaMonkey';
if (ua.search(/Gecko/) > 0) return 'Gecko';
return 'Search Bot';
}
The script looks a bit outdated. The .load() function isn't used like that anymore and browser sniffing is deprecated as well. An approach with the mousewheel plugin (a real gem) would be more reliable and future proof. Here's a script that uses it, making the function itself quite compact :
http://codepen.io/anon/pen/KpPdmX?editors=001
jQuery(window).on('load', function() {
var time = 330;
var distance = 300;
jQuery(this).mousewheel(function(turn, delta) {
jQuery('html, body').stop().animate({
scrollTop: jQuery(window).scrollTop()-(distance*delta)
}, time);
return false;
});
});
// mousewheel.js can be placed here, outside of function scope
It needs a bit of extra script with that plugin but it is well worth it. There also is a wheel event but unfortunately this is still not supported by Opera. In any case, more code would be needed to normalise the delta of the mousewheel turns (this is where mousewheel.js is at it's best).
I'm guessing the $ character is reserved on the web page but if not, the jQuery references could be replaced with it. By the way - you might want to check which version of jQuery is linked to on the site... if there are any other scripts depending on deprecated features (not that there are too many), some things might stop functioning correctly when it is updated. The .on method was introduced in version 1.8 - if you'd like to stick with an older version the above script would need a minor rewrite.
add this function in you script tag
and add data-scroll-speed="10" in your body tag. you can adjust the scroller speed of body
$(function () {
var boxes = $('[data-scroll-speed]'),
$window = $(window);
$window.on('scroll', function () {
var scrollTop = $window.scrollTop();
boxes.each(function () {
var $this = $(this),
scrollspeed = parseInt($this.data('scroll-speed')),
val = -(scrollTop / scrollspeed);
$this.css('transform', 'translateY(' + val + 'px)');
});
});
})
example: fiddled here
check weather this is what you wanted

javascript, zooming in and out of a table

Basically what I want to do is when I scroll up, zoom into my table, making it larger and when I scroll down, zoom out of the table, making it smaller.
Here is the js
var mainGridW = $("#mainGrid").width();
var mainGridH = $("#mainGrid").height();
function setupMouseWheel(){
if (zoomContainer.addEventListener) {
zoomContainer.addEventListener('DOMMouseScroll', onMouseWheelSpin, false);
zoomContainer.addEventListener('mousewheel', onMouseWheelSpin, false); // Chrome
}else{
zoomContainer.onmousewheel= onMouseWheelSpin;
}
}
function onMouseWheelSpin(event) {
var nDelta = 0;
if (!event) { event = window.event; }
// cross-bowser handling of eventdata to boil-down delta (+1 or -1)
if ( event.wheelDelta ) { // IE and Opera
nDelta= event.wheelDelta;
if ( window.opera ) { // Opera has the values reversed
nDelta= -nDelta;
}
}
else if (event.detail) { // Mozilla FireFox
nDelta= -event.detail;
}
if (nDelta > 0) {
HandleMouseSpin( 1, event.clientX, event.clientY );
}
if (nDelta < 0) {
HandleMouseSpin( -1, event.clientX, event.clientY );
}
if ( event.preventDefault ) { // Mozilla FireFox
event.preventDefault();
}
event.returnValue = false; // cancel default action
}
function HandleMouseSpin(delta, x, y) {
if (delta < 0){
mainGridW = mainGridW/1.10;
mainGridH = mainGridH/1.10;
$("#mainGrid").width(mainGridW);
$("#mainGrid").height(mainGridH);
}
if(delta > 0){
mainGridW = mainGridW*1.10;
mainGridH = mainGridH*1.10;
$("#mainGrid").width(mainGridW);
$("#mainGrid").height(mainGridH);
}
}
Here is the html
<body onload="setupMouseWheel();">
<div id="zoomContainer">
<table id="mainGrid" height="100%" width="100%" cellpadding="0" cellspacing="0"></table>
</div>
</body>
This all works, except one problem... In firefox there is a lag before it will work. When I try to scroll it says "not responding" for a few seconds then after it starts to respond again it will work but very slowly. Any ideas? Thanks in advance.
There is lag because onMouseWheelSpin is called repeatedly and too fast. Firefox is not as powerful as webkit browser like Chrome, Safari. To resolve this, you can implement a timer to reduce the work.
var timer;
function onMouseWheelSpin(event) {
if (timer) clearTimeout(timer);
timer = setTimeout(function(){
//your code here
}, 30); //delay
}
And also $("#mainGrid") can be converted to document.getElementById('mainGrid') and .width() with .style.width
When doing animation, native code is always faster than jQuery. By using jQuery, you are trading write less with performance.
I think the 2 events you attached above nearly execute at the same time, thus more lag. When you use a mouse wheel, your page is scrolled. Using a clearTimeout(timer) will prevent the previous call to be terminated

Setting a jScrollPane to autoscroll left and right, but pause on click?

Fiddle: http://jsfiddle.net/RJShm/
I have a jScrollPane that currently scroll from left, to right, then back left, and stops. What I'd like is for this to continually scroll from left to right, the right to left, then repeat. I have this fairly close to working by using pane.bind('jsp-scroll-x'..., but I can't seem to get it to scroll back to the right after one cycle. Current code for that:
pane.bind('jsp-scroll-x', function (event, pos_x, at_left, at_right) {
if (at_right)
{
api.scrollToX(0);
$(this).unbind(event);
}
});
I would also like for this to stop autoscrolling when anything in the pane is clicked (scroll bar, arrows, content, anything), and it would preferably restart after a few seconds of no clicks.
So, in short, how do I:
Make the jScrollPane scroll left/right automatically
Stop autoscrolling when clicked
Restart autoscrolling after a few seconds of no clicks inside the pane
Thanks
EDIT: jScrollPane Settings, and api for your convenience.
I have updated the handler for toggling the infinite scroll and also implemented click handler to pause the scroll and resume after a timeout (5 seconds). See draft code below and check the DEMO: http://jsfiddle.net/p6jLt/
var defaultSettings = {
showArrows: true,
animateScroll: true,
animateDuration: 5000
},
pauseSettings = {
showArrows: true,
animateScroll: false
};
var pane = $('.scroll-pane').jScrollPane(defaultSettings);
var api = pane.data('jsp');
var isFirst = true,
posX = 0,
isLeft = false,
timer;
pane.bind('jsp-scroll-x', scrollFx)
.mousedown(function () {
//lets make sure the below is
//executed only once after automatic croll
if (posX != -1) {
$(this).unbind('jsp-scroll-x');
api.scrollToX(posX);
api.reinitialise(pauseSettings); //no animation
posX = -1;
}
}).mouseup(function () {
clearTimeout(timer); //clear any previous timer
timer = setTimeout(function () {
isFirst = true;
posX = 0; //reset the killer switch
api.reinitialise(defaultSettings); //animateed scroll
pane.bind('jsp-scroll-x', scrollFx); //rebind
api.scrollToX(isLeft ? 0 : api.getContentWidth()); //resume scroll
}, 5000);
});
var scroll = api.scrollToX(api.getContentWidth());
function scrollFx(event, pos_x, at_left, at_right) {
if (posX == -1) { //kill scroll
$(this).unbind(event);
return false;
}
if (at_right) {
api.scrollToX(0);
isLeft = true; //used for restart
} else if (at_left && !isFirst) {
api.scrollToX(api.getContentWidth());
isLeft = false; //used for restart
}
isFirst = false;
posX = pos_x;
}
Issues: The plugin is little buggy with scroll sometimes, but it doesn't break the infinite scroll. You may find the little hicks on scroll, but it works for the most part. Test it out thoroughly and see how it goes.

Adding listener for position on screen

I'd like to set something up on my site where when you scroll within 15% of the bottom of the page an element flyouts from the side... I'm not sure how to get started here... should I add a listener for a scroll function or something?
I'm trying to recreate the effect at the bottom of this page: http://www.nytimes.com/2011/01/25/world/europe/25moscow.html?_r=1
update
I have this code....
console.log(document.body.scrollTop); //shows 0
console.log(document.body.scrollHeight * 0.85); //shows 1038.7
if (document.body.scrollTop > document.body.scrollHeight * 0.85) {
console.log();
$('#flyout').animate({
right: '0'
},
5000,
function() {
});
}
the console.log() values aren't changing when I scroll to the bottom of the page. The page is twice as long as my viewport.
[Working Demo]
$(document).ready(function () {
var ROOT = (function () {
var html = document.documentElement;
var htmlScrollTop = html.scrollTop++;
var root = html.scrollTop == htmlScrollTop + 1 ? html : document.body;
html.scrollTop = htmlScrollTop;
return root;
})();
// may be recalculated on resize
var limit = (document.body.scrollHeight - $(window).height()) * 0.85;
var visible = false;
var last = +new Date;
$(window).scroll(function () {
if (+new Date - last > 30) { // more than 30 ms elapsed
if (visible && ROOT.scrollTop < limit) {
setTimeout(function () { hide(); visible = false; }, 1);
} else if (!visible && ROOT.scrollTop > limit) {
setTimeout(function () { show(); visible = true; }, 1);
}
last = +new Date;
}
});
});
I know this is an old topic, but the above code that received the check mark was also triggering the $(window).scroll() event listener too many times.
I guess twitter had this same issue at one point. John Resig blogged about it here: http://ejohn.org/blog/learning-from-twitter/
$(document).ready(function(){
var ROOT = (function () {
var html = document.documentElement;
var htmlScrollTop = html.scrollTop++;
var root = html.scrollTop == htmlScrollTop + 1 ? html : document.body;
html.scrollTop = htmlScrollTop;
return root;
})();
// may be recalculated on resize
var limit = (document.body.scrollHeight - $(window).height()) * 0.85;
var visible = false;
var last = +new Date;
var didScroll = false;
$(window).scroll(function(){
didScroll = true;
})
setInterval(function(){
if(didScroll){
didScroll = false;
if (visible && ROOT.scrollTop < limit) {
hideCredit();
visible = false;
} else if (!visible && ROOT.scrollTop > limit) {
showCredit();
visible = true;
}
}
}, 30);
function hideCredit(){
console.log('The hideCredit function has been called.');
}
function showCredit(){
console.log('The showCredit function has been called.');
}
});
So the difference between the two blocks of code is when and how the timer is called. In this code the timer is called off the bat. So every 30 millaseconds, it checks to see if the page has been scrolled. if it's been scrolled, then it checks to see if we've passed the point on the page where we want to show the hidden content. Then, if that checks true, the actual function then gets called to show the content. (In my case I've just got a console.log print out in there right now.
This seems to be better to me than the other solution because the final function only gets called once per iteration. With the other solution, the final function was being called between 4 and 5 times. That's got to be saving resources. But maybe I'm missing something.
bad idea to capture the scroll event, best to use a timer and every few milliseconds check the scroll position and if in the range you need then execute the necessary code for what you need
Update: in the past few years the best practice is to subscribe to the event and use a throttle avoiding excessive processing https://lodash.com/docs#throttle
Something like this should work:
$(window).scroll(function() {
if (document.body.scrollTop > document.body.scrollHeight * 0.85) {
// flyout
}
});
document.body.scrollTop may not work equally well on all browsers (it actually depends on browser and doctype); so we need to abstract that in a function.
Also, we need to flyout only one time. So we can unbind the event handler after having flyed out.
And we don't want the flyout effect to slow down scrolling, so we will run our flytout function out of the event loop (by using setTimeout()).
Here is the final code:
// we bind the scroll event, with the 'flyout' namespace
// so we can unbind easily
$(window).bind('scroll.flyout', (function() {
// this function is defined only once
// it is private to our event handler
function getScrollTop() {
// if one of these values evaluates to false, this picks the other
return (document.documentElement.scrollTop||document.body.scrollTop);
}
// this is the actual event handler
// it has the getScrollTop() in its scope
return function() {
if (getScrollTop() > (document.body.scrollHeight-$(window).height()) * 0.85) {
// flyout
// out of the event loop
setTimeout(function() {
alert('flyout!');
}, 1);
// unbind the event handler
// so that it's not call anymore
$(this).unbind('scroll.flyout');
}
};
})());
So in the end, only getScrollTop() > document.body.scrollHeight * 0.85 is executed at each scroll event, which is acceptable.
The flyout effect is ran only one time, and after the event has returned, so it won't affect scrolling.

Categories

Resources