It is possible to improve scrolling on a list with large number of containing objects.
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
<li>text4</li>
<li>...</li>
.
.
.
<li>text1000</li>
</ul>
Whenever I scroll over 90% of the elements in container, I make a js call that will load more results to my container and will add my rest of the elements to the ul.
Can I modify the scroll speed when scrolling based on the number of the results?
p.s. I don't have any code that I have tried on this situation. I don't know how to do this. This is the last attempt in order to solve a problem that I have.
p.s. 2 i would like a solution without any extra library than jquery or jqm.
Edit:
By modify the scroll speed I mean to change the scroll to go faster if there are many objects and slower otherwise
You can use this kind of snippet:
{Change timeout delay for less boring effect using scrollbar}
SEE DEMO
(function () {
var $ul = $('ul');
for (var i = 1; i < 1001; i++)
$ul.append('<li>test::' + i + '</li>');
var lastScrollTop = 0,
st,
direction;
function getDirection() {
st = window.pageYOffset;
if (st > lastScrollTop) {
direction = "down";
} else {
direction = "up";
}
lastScrollTop = st;
return direction;
}
var scrolling = function () {
var $window = $(this);
$window.off('scroll');
var delta = $ul.height() / 10,
scroll = $window.scrollTop();
if (getDirection() === "down") $window.scrollTop(delta + scroll);
else $window.scrollTop(scroll - delta);
console.log($(window).scrollTop());
lastScrollTop = this.pageYOffset;
setTimeout(function () {
$window.on('scroll', scrolling);
}, 0);
};
$(window).on('scroll', scrolling);
})();
Related
I have written some javaScript so that my menu starts off as position: static but will become position: fixed and stay at the top of the screen whenever the user scrolls upwards but will disappear again whenever scrolling downwards. Because the menu has some content above it, once the user has scrolled to the very top, the menu becomes position: static again.
This code works ok but I am having a problem when adding debounce. I've read I need either throttling or debounce for performance. I have tried using both the Lodash _.debounce and _.throttle functions separately. I don't mind having some delay on the menu showing itself on scroll-up, but with a debounce the header has a delay when returning to position: static once the user has scrolled back to the top of the page. I have tried using the {'leading': true} option for the debounce and throttle function but it hasn't done much good.
If I set my wait/delay time too low, surely there is no point in even using debounce or throttle anymore? I do not want to sacrifice the performance of the site but have been asked to implement this effect.
var header = document.getElementById("fixed-header");
var offset = header.offsetTop;
var $header = $(header);
var headerHeight = parseInt($header.css("height"));
var total = headerHeight + offset;
var lastScrollTop = 0;
window.addEventListener("scroll", _.debounce(scrollHeader, 200, {
'leading': true
}));
function scrollHeader() {
var st = window.pageYOffset || document.documentElement.scrollTop;
if (st > lastScrollTop) {
// downscroll code
if (pageYOffset >= total) {
document.body.classList.add("fixed");
document.body.classList.add("is-hidden");
document.body.style.paddingTop = header.offsetHeight + "px";
header.style.transition = ".5s";
} else {
document.body.classList.remove("fixed");
document.body.classList.remove("is-hidden");
document.body.style.paddingTop = 0;
}
} else {
// upscroll code
if (pageYOffset >= offset) {
document.body.classList.add("fixed");
document.body.classList.remove("is-hidden");
document.body.style.paddingTop = header.offsetHeight + "px";
} else {
header.style.transition = "initial";
document.body.classList.remove("fixed");
document.body.style.paddingTop = 0;
}
}
lastScrollTop = st;
}
Hey Guys I found this really useful java script sticky side nav, and it works great! I don't much about js, i was just wondering if there was away to slow down the scrolling?
function redrawDotNav(){
var topNavHeight = 50;
var numDivs = $('section').length;
$('#dotNav li a').removeClass('active').parent('li').removeClass('active');
$('section').each(function(i,item){
var ele = $(item), nextTop;
console.log(ele.next().html());
if (typeof ele.next().offset() != "undefined") {
nextTop = ele.next().offset().top;
}
else {
nextTop = $(document).height();
}
if (ele.offset() !== null) {
thisTop = ele.offset().top - ((nextTop - ele.offset().top) / numDivs);
}
else {
thisTop = 0;
}
var docTop = $(document).scrollTop()+topNavHeight;
if(docTop >= thisTop && (docTop < nextTop)){
$('#dotNav li').eq(i).addClass('active');
}
});
}
$('#dotNav li').click(function(){
var id = $(this).find('a').attr("href"),
posi,
ele,
padding = $('.navbar-fixed-top').height();
ele = $(id);
posi = ($(ele).offset()||0).top - padding;
$('html, body').animate({scrollTop:posi}, 'slow');
return false;
});
demo
The line in your JavaScript code doing that is this:
$('html, body').animate({scrollTop:posi}, 'slow');
You can change the 'slow', to 'fast', and see the difference.
Learn more about the animate function here.
You can precisely control the speed on animate with duration. Here is the function signature:
animate(params, [duration], [easing], [callback])
The strings fast and slow can be supplied to indicate durations of 200ms and 600ms, respectively. The default speed is 400ms. You can adjust your speed by replacing nnn with the exact speed in milliseconds you want.
$('html, body').animate({scrollTop:posi}, nnn);
I'm trying to obtain this effect (you need to scroll down a bit to see the divs sliding in)
I'm not that good with JS but I managed to make the divs fade in from 0 opacity to full opacity using this code:
tiles = $(".recipe").fadeTo(0, 0);
$(window).scroll(function(d,h) {
tiles.each(function(i) {
a = $(this).offset().top + $(this).height();
b = $(window).scrollTop() + $(window).height();
if (a < b) $(this).fadeTo(500,1);
});
});
Can anyone help me optain the desired effect? I need the divs to slide up from 0 opacity to 100 percent opaque, from bottom to top, when scrolling.
Hope this makes sense, thanks.
I think this is a possible solution:
var scrollCb = function () {
var tiles = $(".tile:not(.animated)");
var $window = $(window);
var b = $window.scrollTop() + $window.height();
tiles.each(function (i) {
var $this = $(this);
var a = $this.offset().top + $this.height();
if (a < b) {
$this.addClass("animated").addClass("fadeInUp");
}
});
};
$(scrollCb);
$(window).scroll(scrollCb);
http://jsfiddle.net/74u765q2/4/
animate.css realizes the animation part.
That page uses a jquery library called waypoints.
You have to download the waypoint library, this library has a lot of functions for scroll event:
for example:
$('#example-offset-percent').waypoint(function() {
notify('25% from the top');
}, { offset: '25%' });
this code triggers the notify when the object is 25% from the top of the screen.
here is the link to the page:
http://imakewebthings.com/jquery-waypoints/
I added some special features to the sidebar of my webapplication. You can see a concept of the user interface on my testing site. (It's about the right sidebar)
The sidebar stops scrolling if it is scrolled to its end.
Moreover there are selected listitems in the sidebar wich stay on the top or the bottom of the sidebar if they would scroll out of the view.
My code is written in Javascript using jQuery. Unfortunately scrolling on my page is lagging now. Here are the links to my demo page (rightclick -> show sourcecode) and its javascript file.
How can I speed up the code (and let is still abstract) ?
I paste the javascript code here for those of you who don't want to follow the links.
HTML: (example)
<ul id="right">
<li><h3>Headline</h3></li>
<li><a>Item</a></li>
<li><a>Item</a></li>
<li><a class="selected">Active Item</a></li>
<li><a>Item</a></li>
<li><h3>Headline</h3></li>
<li><a>Item</a></li>
<li><a>Item</a></li>
</ul>
Javascript:
var Scrollers = $('#content,#left,#right');
var Scrollable = new Array(Scrollers.length);
var TopOffset = new Array(Scrollers.length);
var BottomOffset = new Array(Scrollers.length);
var OuterHeight = new Array(Scrollers.length);
var OuterHeightAndOffsets = new Array(Scrollers.length);
function ScrollInit(){
Scrollers.each(function(i){
// constants
TopOffset[i] = parseInt($(this).css("margin-top").replace("px",""));
BottomOffset[i] = parseInt($(this).css("margin-bottom").replace("px",""));
OuterHeight[i] = parseInt($(this).outerHeight());
OuterHeightAndOffsets[i] = TopOffset[i] + BottomOffset[i] + OuterHeight[i];
// classes
$(this).removeClass('snapped top bottom');
if(OuterHeightAndOffsets[i] < $(window).height()){
$(this).addClass('snapped top');
Scrollable[i] = false;
} else {
Scrollable[i] = true;
}
});
}
ScrollInit();
var SelectedListitems = $('li.selected');
var SelectedListitemsActive = new Array(SelectedListitems.length); for(var i=SelectedListitems.length; i<0; i++) SelectedListitemsActive[i] = false;
function ScrollCalc(){
// list item locking
SelectedListitems.each(function(i){
if(!($(this).parent().hasClass('snapped top'))){
var ListItemOffset = $(this).offset().top - $(window).scrollTop();
var ListItemState=0; // 0:in, 1:above, 2:under
if(ListItemOffset <= $(this).parent().offset().top){ ListItemState=1; }
else if(ListItemOffset + $(this).outerHeight() >= $(window).height()){ ListItemState=2; }
// no snapped clone so far
if(ListItemState){
if(SelectedListitemsActive[i]!=true && !$(this).parent().hasClass('snapped')){
var AppendClasses = 'clone snapped '; if(ListItemState == 1) AppendClasses += 'top '; else AppendClasses += 'bottom ';
$(this).parent().append($(this).clone().addClass(AppendClasses + i));
SelectedListitemsActive[i] = true;
}
// already snapped, clone existing
} else {
if(SelectedListitemsActive[i]==true){
$('.clone.snapped.' + i).remove();
SelectedListitemsActive[i] = false;
}
}
}
});
// scroll container locking
Scrollers.each(function(i){
if(Scrollable[i]){
if($(window).scrollTop()+$(window).height() > OuterHeightAndOffsets[i]){
$(this).addClass('snapped bottom');
} else {
$(this).removeClass('snapped bottom');
}
}
});
ScrollEvent = false;
}
ScrollCalc();
$(window).scroll(function(){
ScrollCalc();
});
I've just have a look at you link and believe that the lagging is not because of your javascript. If you don't think so try to disable all scripts in window.scroll event, still lagging right?
Now try to remove all shadow properties - box-shadow and text-shadow. Also remember to disable changing shadow opacity in simple.js (changing shadow during scroll event always laggy).
Now you can see it run very fast!!! Back to css file and enable each shadow properties and find out what is most suitable for you.
There is a much faster, easier way to get the effect you want.
Try this: when the window scrolls down far enough, set your sidebar's css position property to fixed. When it scrolls up, set the position of the sidebar back to relative.
var sidebar = document.getElementById('side'),
section;
sidebar.style.position = 'relative';
sidebar.style.bottom = '0px';
sidebar.style.right = '0px';
window.onscroll = function(){
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
maxTop = section ? section.offsetTop : sidebar.offsetHeight - window.innerHeight;
sidebar.style.top = sidebar.style.bottom = null;
if (scrollTop > maxTop) {
if (section) {
sidebar.style.top = - section.offsetTop + 'px';
} else {
sidebar.style.bottom = '0px';
}
sidebar.style.position = 'fixed';
} else {
sidebar.style.position = 'relative';
}
}
You can see it working here - http://jsfiddle.net/cL4Dy/
I'm wondering if there is a simple way to make use of JavaScript (probably jQuery too?) in order to make the contents of a fixed-height div element scroll infinitely up and down (top, bottom, top, bottom, etc) when the page loads and without any user input or manipulation?
Thanks ahead of time, any input is greatly appreciated as I am hardly mediocre with JavaScript.
With pure js you can do something like this:
var scroller = document.getElementById('scroller');
var delta = 15;
var lastSc;
//console.log(scroller.scrollTop, scrollHeight);
setInterval(function(){
var sc = scroller.scrollTop + delta;
scroller.scrollTop = sc;
if (scroller.scrollTop === lastSc){
delta = delta*(-1);
}
lastSc = scroller.scrollTop;
}, 10);
Here is demo
Edit: updated demo
Here is something I've just written, using jQuery:
var speed = 100; //smaller means faster
var offset = 5; //bigger means more text will be "scrolled" every time
function ScrollMyDiv() {
var myDiv = $("#MyDiv");
var direction = myDiv.attr("scroll_dir") || "";
var lastScrollTop = parseInt(myDiv.attr("last_scroll_top") || "0", 10);
if (direction.length === 0) {
myDiv.attr("scroll_dir", "down");
direction = "down";
}
var top = myDiv.scrollTop();
myDiv.attr("last_scroll_top", top + "")
if (direction === "down") {
if (top > 0 && lastScrollTop === top)
myDiv.attr("scroll_dir", "up");
top += offset;
} else {
if (top <= 0)
myDiv.attr("scroll_dir", "down");
top -= offset;
}
myDiv.scrollTop(top);
window.setTimeout(ScrollMyDiv, speed);
}
$(document).ready(function() {
ScrollMyDiv();
});
Live test case: http://jsfiddle.net/HmfNJ/1/
Basically, it will start by scrolling down (adding to the scrollTop) then when it identify it reached the bottom by seeing the scrollTop remains the same, it will change direction and start scroll up.
Thanks for the replies but I found my answer elsewhere. Here's what I ended up using: http://jsbin.com/onohan/3/edit#preview
It had a couple of small problems but I at least knew enough about basic JavaScript to fix them. Hopefully this will benefit someone in the future. :)
To get a smooth transition for scroll to bottom this is VanillaJS code that works well with me
var delta = 0.6, interval;
interval = setInterval(function(){
window.scrollBy(0, delta);
}, 20);
To clear the Interval you can run
clearInterval(interval);