Making my JavaScript scroll function smooth - javascript

Hello my current JavaScript is this, to scroll the page to an id tag further down my website page:
function scroll(element){
var ele = document.getElementById(element);
window.scrollTo(ele.offsetLeft,ele.offsetTop);
window.scrollBy(0, -100);
}
How can I make the function scroll smoothly ?

First of all, this is not Java, this is JavaScript, and those two are different, they are not just two names for one programming language...
For your problem, I would do something like getting the current position of the scroll by using document.documentElement.scrollTop (but this one returns 0 on chrome) and the wanted position of the scroll by getting your element's coordinates, and then just move the scroll for a bit of the distance every frame by using window.scrollBy() method.
However, I would not suggest this method, because there are other, better solution would be to use this

Related

Scroll to a specific location using only Javascript when scrollTop() is not working?

So my problem is a bit specific.
The first thing is that due to something (I don't know what) the result of any element of the page .scrollTop equal 0
This makes the use of scrollTop() impossible.
However I can use scrollIntoView() BUT I need to add a specific height to my element.
Something like document.getElementById(ELEMENT).scrollIntoView() + 50px.
So I wanted to know what does scrollIntoView() takes in account (since its not scrollTop) and if I could edit this value to manage what I want?
Or maybe you do have an other solution for me?
Edit: This is the page I'm trying to scroll in https://www.naissance.fr/prenoms/ and this is the bloc I want to scroll to (without the navigator over it) : document.getElementsByClassName('mastcontainer__body')[0].scrollIntoView(true);
I guess this is what you have been looking for,
To get the position of any element in page, you can use 'getBoundingClientRect' method like this, and window.scrollTo() to scroll to that particular location.
var htmlElement = document.getElementById('container');
var elementPosition = element.getBoundingClientRect()
window.scrollTo(elementPosition.top, elementPosition.left)
Also refer this link for more learning: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

jquery animate/scrollTop to multiple anchors inside divs

I'm having a problem implementing relatively complicated auto-scroll functionality on my page. This displays the issue in my code...
http://codepen.io/d3wannabe/pen/XXxdQq
I have multiple divs on my page (blue,red,green in my example) that I not only want to be able to scroll to (which the top 3 buttons in my example achieve perfectly), but I want to be able to scroll WITHIN (which the bottom 3 buttons represent my best attempt at).
The thing I can't figure out, is why the scroll within function works well on my first div ("scrollTo3rdBlueItem" button), but then less accurately with the other divs ("scrollTo3rdRedItem" and "scrollTo3rdGreenItem" buttons). In my full web application (which obviously has more data to scroll through), I basically see that the lower down the page the parent div is positioned, the less accurately I'm able to scroll within it.
I'm struggling to identify much of a pattern though so can't simply try tweaking the offset values. Any ideas what I might be doing wrong here would be hugely appreciated!!
...since I wasn't allowed to post this without quoting code - here's the jquery function you can see in my codepen!
function scrollToParent(parentID){
$('html,body').animate({scrollTop: $('#'+parentID).offset().top}, 500);
}
function scrollToChild(parentID, childID){
//first focus on the parent
scrollToParent(parentID);
$('#'+parentID).animate(
{scrollTop: $('#'+ childID).offset().top - 100}
, 500);
}
UPDATE
Answer here was COMPLETETLY wrong. Left here to preserve the comments.
UPDATE 2
Got IT! You need to take in to account the offset of the parent div. Update your scrollToChild function to the below;
$('#'+parentID).animate(
{
scrollTop: $('#'+ childID).offset().top - $('#'+parentID).offset().top
}, 500);

How to improve JS scroll performance?

I'm working on revamping my website, and the new one can be found on http://beta.namanyayg.com/
There are mainly two things related to scroll on the site:
To check on which 'page' the user is on, by calculating the top offset and scroll position, then adding a class to the page.
To smooth scroll on menu click.
I've written code for both, but there is a lot of lag.
The first one almost always results in lagging. The second one, as a result, lags too. I have included a boolean to check if it's smooth scrolling and disabled the normal scroll events then, but there's not much change.
Do you have any advice on how to improve performance so there is no (or at least, less) lag? Thank you in advance! :)
...Or is it not related to JS at all? I've optimized everything else...
EDIT: Unminified JS at http://beta.namanyayg.com/js/main.js
If you are using underscore, it has an awesome _.debounce function that is excellent for this sort of thing.
To check how much the user has scrolled from the top of the page (i.e. on which 'page' he is at the moment) can be achieved with:
$(window).scroll(function () {
var scrollAmount = $(window).scrollTop(); // in pixels
if(scrollAmount > SOME_AMOUNT)
{
// add required css class
}
});
To scroll smoothly, to some id for example, you could use:
$("html, body").animate({ scrollTop: $("#someID").scrollTop() }, 1000);
These are both jQuery solutions, so you should have jquery library included. There is also a nice jQuery plugin called waypoints that performs these calculations. It might prove useful to you and it has some other nice features and examples.
I have the same problem. I have a scrollable div with thousands of smaller divs. Every time I call scrollTop to get the scroll-position or set it, it sometimes waits at least 1 second.
I read these slides: http://www.slideshare.net/nzakas/high-performance-javascript-2011 (especially slides 138-139) and now I realize that every call to scrollTop, even as a getter, makes javascript relayout the page. This is most likely the cause of delay, but unfortunately I have not found a solution yet, as in a way to call scrollTop without causing relayouts.
Note: I've only been testing on Chrome.
Also read 'Browsers are smart' section of this article: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
I've found an easy solution to the lag with getting scrollTop, just call it inside a scroll-handler and save the result in a variable.
for example in jQuery:
var scrollPos = 0,
element = $('.class');
element.scroll(function(){
scrollPos = element.scrollTop();
});
For the second problem, setting the scrollTop, I reduced the amount of DOM elements by only showing the visible elements. In your case make sure only the visible page(s) are added to the DOM. when scrolling to the next page, in the scroll handler remove the top one (use jQuery .detach) and append the next one to the DOM.

How to calculate offsetTop of element within div - returns null?

I have a div "content" with anchor id="one" inside of it.
Right now, I am using an onClick event from an exterior link to scroll "content" by a pixel distance to bring "one" into view without making the rest of the page jump and it works nice and smooth as planned...
onClick="document.getElementById('content').scrollTop = 400;
but I would rather calculate the exact offsetTop distance of "one" and scroll by that distance instead of my arbitrary numbers.
This is what I am trying:
<script type="text/javascript">
<!--
var topPos = document.getElementById('one').offsetTop;
//-->
</script>
and
onClick="document.getElementById('content').scrollTop = topPos;
with
<a id="one"></a> being how I ID the element within the content.
But topPos returns null! I can't seem to get past this. I don't know if it's my poor javascript skills (probably) or the fact that my css isn't providing any numbers. I am not using fixed positioning, if this matters. Can anyone tell me my glaring error? Thanks in advance.
Any reason not to use scrollIntoView()?
https://developer.mozilla.org/en/DOM/element.scrollIntoView
Depending on where the script is located, it may be because the browser does not yet have enough info to retrieve the topPos. Try placing the script at the bottom of the page or run it in response to a page load event.
Alternatively, instead of calculating ahead, just have onClick call a function to calculate the position and set the scroll.

How to make an element slide with the viewport as it scrolls?

I've Googled for this but must be using the wrong keywords.
Basically I want to use the effect that Magento and now Stack Overflow uses. That is, there is an element in a column, and when you scroll down, it sticks to the top of the viewport. And once scrolled up again, it goes back into the normal page flow.
This Ask A Question is a good page for example. Scroll down and watch the "How to Format" element come down (might need to make your viewport smaller if you have a large screen to see the effect).
I've noticed it is setting position: fixed in the CSS. The JavaScript however is obfuscated.
What's the easiest way to achieve this effect? Is there a jQuery plugin available?
Here is an article that should help: http://www.wduffy.co.uk/blog/keep-element-in-view-while-scrolling-using-jquery/comment-page-1/
I noticed google doing this in certain places, like here http://news.google.com/nwshp?hl=en (the left side navigation bar). From what I can tell, they checking the position on the page and then setting the item to a fixed position once the page is scrolled down enough for the element to start scrolling off the screen.
It looks like the other method, using jQuery to set the top margin will allow the element to lag behind and get choppy (if you don't use animation) since the javascript must continue to position the element.
Here is an example in Ext, it would probably help a lot if I didn't have the select in the event handler, but it works.
Ext.fly(document).on("scroll", function(e,t,o){
Ext.select(".pinnable").each(function(el,c,idx){
var y = window.scrollY;
if(!el.hasClass("pinned")){
var ypos = el.getY();
if(y>ypos){
el.addClass("pinned");
el.set({
originalY:ypos
});
}
} else {
var origy = el.getAttribute("originalY");
if(origy && y<origy){
el.removeClass("pinned")
}
}
});
});

Categories