iamdustan / smoothscroll Goto Github PK
View Code? Open in Web Editor NEWScroll Behavior polyfill
Home Page: http://iamdustan.com/smoothscroll/
License: MIT License
Scroll Behavior polyfill
Home Page: http://iamdustan.com/smoothscroll/
License: MIT License
document.getElementById("top").scrollIntoView({ behavior:"smooth" });
scrolls to 1px shy of the top of the page. The element is at the same y location as <body>
and <html>
.
The issue does not occur when not using smooth behaviour -- even in Safari, which does not have any native implementation of this function.
The version on npm is not the latest code, can you please release an up-to-date version?
Package is not in npm directory: https://www.npmjs.com/package/smoothscroll
Make sure you have the last version and run npm publish
.
DUPICATE of #28
@iamdustan
Hi,
Thank you for useful library. It helps me very well.
But I found a case Chrome doesn't work fine. A picture is worth a thousand words, you can see that at here:
https://kitaitimakoto.github.io/smoothscroll/#nesting
Links to "Nesting child 0X" don't lead you to target section but the top of "Nesting" section when using Chrome. Firefox and Safari work fine.
Do you have any idea about this behavior and fixing it?
My example's source code is here:
https://github.com/iamdustan/smoothscroll/compare/master...KitaitiMakoto:nesting?expand=1
Thanks.
window.addEventListener('keydown', () => (window.scrollBy({ top: 40, behavior: 'smooth' })))
Would a PR be welcome to add support for this?
I've noticed that Firefox is the only browser which has this behavior enable by default. The thing is that inside the window.scroll
declaration it expects an object while it still gives supports for the old two number arguments.
window.scroll({
top: 120,
left: 20,
behavior: 'smooth'
});
Since Firefox is expecting this, the script will return because it finds that smoothBehavior
is implemented and never work.
If you are ok with this, I can create a pull request with all the necessary changes to adapt your script to this type of call which I guess is the standard one instead of the actual that doesn't have an options object.
Hi I have tested this in the stable branch of chrome in both versions using the demo page.
I assume it is because chrome doesn't have the full implementation so the polyfill thinks it is fully supported natively in the browser but it isn't as smooth
isn't supported.
Hopefully someone else can confirm.
The smooth scroll behaviour doesn't take affect for scrollIntoView
in chrome 52 for some reason.
The behaviour is fine for scrollBy
and other functions though.
Tested on http://iamdustan.com/smoothscroll/
It seems that the latest WD has scroll, scrollTo, scrollBy methods on Element interface. Will this polyfill support them?
partial interface Element {
...
void scroll(optional ScrollToOptions options);
void scroll(unrestricted double x, unrestricted double y);
void scrollTo(optional ScrollToOptions options);
void scrollTo(unrestricted double x, unrestricted double y);
void scrollBy(optional ScrollToOptions options);
void scrollBy(unrestricted double x, unrestricted double y);
...
};
Any chance you plan on adding support for Element.scrollIntoViewIfNeeded()?
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded
Dustan, if you can, go to settings and make GitHub page to grab the content in master, this will make docs maintainance easier.
I've come across a strange situation where Firefox's native scrollIntoView
implementation behaves strange and unnatural, whereas the polyfill works perfectly.
Thus I think there should be an option to always override this behaviour (for some special cases).
import { polyfill } from 'smoothscroll-polyfill';
console.log(polyfill) // empty object
import polyfill from 'smoothscroll-polyfill';
console.log(polyfill) // empty object
import { polyfill } from 'smoothscroll-polyfill/src/smoothscroll';
console.log(polyfill) // function! works!
I guess the issue is that the dist file does not contain module.exports
but only exports
.
please
IE11 has a wonderful rounding bug, which means that if an element has a calculated height that ends in a fraction of a pixel, then clientHeight
can be end up being rounded down to the nearest whole pixel, while scrollHeight
is rounded up.
In this scenario, while findScrollableParent
is traversing up though the DOM structure, it can encounter an element where there is a 1px difference between the clientHeight
and scrollHeight
, which results in the function's loop exiting too early.
I'd suggest altering the hasScrollableSpace
check to see if the height and width are within a 1px tolerance of each other to fix this. Granted, this could be seen as introducing inaccuracy into the calculations. I'd be interested to hear other's thoughts on the matter.
NB: This very probably affects other versions of IE & Edge in addition to IE11.
EDIT: Someone else has kindly set up a jsfiddle demo of a scenario where IE11 reports the mismatching values when it shouldn't. http://jsfiddle.net/bmwz9/3jnr6/
Screenshot of the output of the jsfiddle in IE11 (for anyone without that browser to hand):
I'm using this .js in an Angular 4 app. It works well in all the browsers except in Firefox 54. In that version is has no scroll.
document.getElementById('foo').scrollIntoView({ behavior: 'smooth' });
This is an example of code that I'm using.
Please suggest any fix or workaround.
Thank you.
[EDIT]
So the issue seems to disappear if we don't have the following instruction in the same "scope" of the previous one:
window.scroll(0, window.scrollY - 50);
(we did this to adjust the position after the scroll).
So to be clear: if we have both instructions, there is no scroll at all... if only the first one exists, then we have a smooth scroll.
That being said, I'm not sure if this is a bug related to your polyfill but it's worth checking out I think.
Thank you
Please use exports.default
instead of setting module.exports
to avoid this error when importing with ES6 Modules syntax:
export 'default' (imported as 'smoothscroll') was not found in 'smoothscroll-polyfill'
I'm not sure which is correct, I suspect the later, but there seems to be two demo sites floating around:
http://iamdustan.com/smoothscroll/
and
https://ghybs.github.io/smoothscroll/
The second page includes element.scroll
and element.scrollTo
methods which are not featured in the first demo page but do seem to work with the latest npm release
Thanks
Joe
The smooth behaviour doesn't work on Chrome even on the demo website when selecting elements to scroll to.
Google Chrome 56.0.2924.3 (Official Build) dev (64-bit)
Revision 66f73b3ae5a592d70e00602e87a783535ffe967e-refs/branch-heads/2924@{#54}
How to reproduce:
document.querySelector('header').scrollIntoView({ behavior: 'smooth' });
or
document.querySelector('.hello').scrollIntoView({ behavior: 'smooth' });
Expected result: smooth scrolling.
Actual result: jump scrolling.
Hi, first thanks for the polyfill!!
When using scrollIntoView on an element where the Y-Axis is already in the view but X-Axis is not, the Y-Axis seems to be manipulated too (see test case with polyfill).
Please test the 2 test cases by manually scrolling up and down. An interval is set to alternately call scrollIntoView on the nav anchors.
Expected: no effect on the Y-Axis. Scrolls the X-Axis of the nav element
Issue: "With the pollyfill" the Y-Aixs seems to be unnecessary modified. Manually scrolling the Y-Axis is hindered when scrollIntoView is called. (issue on chrome, no issue on firefox)
without polyfill
https://jsfiddle.net/tofu/245w4hxe/10/
with polyfill
https://jsfiddle.net/tofu/245w4hxe/12/
Can I use this library to scroll a specific element to a custom position?
// I need an alternative to this:
var element = document.getElementById('outer'); // An Element object.
element.scrollLeft = 100; // Custom horizontal position.
window.scroll
, window.scrollTo
, window.scrollBy
or Element.scrollIntoView
does not help in this case.
Given this is a polyfill, I don't think it supports anything that will not eventually supported natively by the browsers. But since I already have this as a dependency that contains smooth-scrolling logic, I was curious if I could somehow take advantage of that without copying the internals.
I think this has something to do with the reuse of window.scrollTo
in this method:
https://github.com/iamdustan/smoothscroll/blob/master/smoothscroll.js#L71
That will try to scroll to a specific location int the document, but it doesn't work for
elements with overflow:scroll
...the primary use case for el.scrollIntoView()
.
This is especially true if body has overflow:hidden
. Nothing will happen.
Hi,
0.0.4 doesn't seem available as a tag so Bower won't pick it up.
This line will come back as undefined
if there's no scrollable parent when the function is run. This causes the next line to throw an error. It's not an unlikely scenario, either. If the parent element has overflow: auto
then it won't be scrollable until there's enough content in the pane to overflow.
Unfortunately, I don't have isolated test-case, but issue is constantly/easily reproduced here (scroll down to News & Media ) with Chrome 58/Win.
Note: this is about horizontal scrolling of a div with overflow-x: scroll
style.
The test case is (to run from DevTools on the page above, one command a time):
document.querySelector('.news-feed').scrollBy({ left: 2000 }); //OK
document.querySelector('.news-feed').scrollLeft = 0; // OK
After that everything is still fine - scroll is back to 0.
document.querySelector('.news-feed').scrollBy({ left: 2000, behavior: 'smooth' }); // OK
document.querySelector('.news-feed').scrollLeft = 0; // Fail and scroll is broken!
=> After that scroll is broken: neither scrollLeft
is back to 0, nor scrolling with mouse is possible. Which is a deal-breaker.
Forcing commonjs to use smoothscroll.polyfill()
makes it a bit lame to use with es6 modules.
import smoothscroll from 'smoothscroll-polyfill'
smoothscroll.polyfill()
vs
import 'smoothscroll-polyfill'
Is there any benefit to forcing .polyfill
to be called?
I have a modal and I'm scrolling to tabbed sections with it. Unfortunately no scroll()
on container elements yet to do it manually, and scrollIntoView()
scrolls the main window body in the background too.
findScrollableParent returns false positive if margin collapsing(bleeding) occurs on element. (scrollHeight is greater than clientHeight, but there is no scrolling).
The default behavior for an anchor jumps the window to where the top of the element is at the top of the viewport. Is this not possible with smoothscroll?
It would be great if smoothscroll-polyfill would be available on cdnjs. What do you think?
Thanks for the great library :)
Just tried this out and the performance is perfect, but I lack the ability to scroll an element into view while accommodating for a fixed element like a header. Would be great to have an extra argument in for the scrollIntoView method that would let you push the element up or down.
I've assign window.scrollTo(0, position, 'smooth') when an anchor is clicked. If there's a scrolling taking place the function stops working. To fix this, I made frame a global variable and call cancelAnimationFrame() before a new one starts:
cancelAnimationFrame(frame);
frame = requestAnimationFrame(step);
The MDN docs for scroll() and scrollBy() don't mention the 'behavior' option, or the way of calling it with a single options argument ({left, top, behavior}
) as in test.html.
Is this because the MDN docs are incomplete, or because smoothscroll implements extra features not in the spec?
Either way it would be good to give some usage examples in the readme.
Hi,
I have a quick question about this SCROLL_TIME
: https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js#L22
I just wonder how did you get this number 😸
The polyfill should shift focus to the target element after scrolling. This allows keyboard users to continue tabbing without being sent back up to the original link location.
I’ve used the technique below in my own custom smooth scroll scripts and it’s worked great:
// Setting 'tabindex' to -1 takes an element out of normal
// tab flow but allows it to be focused via javascript
$el.attr('tabindex', -1).on('blur focusout', function() {
// when focus leaves this element,
// remove the tabindex attribute
$(this).removeAttr('tabindex');
}).focus(); // focus on the content container
Source: https://www.bignerdranch.com/blog/web-accessibility-skip-navigation-links/
Thanks for your work on this script! Looking forward to switching to it once this a11y issue is addressed (I would submit a PR but don’t have time right now, unfortunately).
0(11:54:36) <project directory>/node_modules/smoothscroll [master]
$ npm run build
> [email protected] build <project directory>/node_modules/smoothscroll
> gulp
[11:57:14] Using gulpfile <project directory>/node_modules/smoothscroll/gulpfile.js
[11:57:14] Starting 'lint'...
[11:57:16] 'lint' errored after 2.62 s
[11:57:16] ESLintError in plugin 'gulp-eslint'
Message:
Expected indentation of 4 space characters but found 2.
Details:
fileName: <project directory>/node_modules/smoothscroll/src/smoothscroll.js
lineNumber: 2
[11:57:16]
<project directory>/node_modules/smoothscroll/src/smoothscroll.js
2:3 error Expected indentation of 4 space characters but found 2 indent
2:3 error 'use strict' is unnecessary inside of modules strict
12:3 error Expected indentation of 4 space characters but found 2 indent
14:5 error Expected indentation of 6 space characters but found 4 indent
15:7 error Expected indentation of 8 space characters but found 6 indent
21:5 error Expected indentation of 6 space characters but found 4 indent
22:5 error Expected indentation of 6 space characters but found 4 indent
27:5 error Expected indentation of 6 space characters but found 4 indent
28:7 error Expected indentation of 8 space characters but found 6 indent
29:7 error Expected indentation of 8 space characters but found 6 indent
30:7 error Expected indentation of 8 space characters but found 6 indent
36:5 error Expected indentation of 6 space characters but found 4 indent
45:5 error Expected indentation of 6 space characters but found 4 indent
46:7 error Expected indentation of 8 space characters but found 6 indent
47:7 error Expected indentation of 8 space characters but found 6 indent
56:5 error Expected indentation of 6 space characters but found 4 indent
57:7 error Expected indentation of 8 space characters but found 6 indent
66:5 error Expected indentation of 6 space characters but found 4 indent
66:5 error Function 'normalizeArgs' has a complexity of 9 complexity
67:7 error Expected indentation of 8 space characters but found 6 indent
68:9 error Expected indentation of 10 space characters but found 8 indent
69:11 error Expected indentation of 12 space characters but found 10 indent
70:11 error Expected indentation of 12 space characters but found 10 indent
74:7 error Expected indentation of 8 space characters but found 6 indent
75:9 error Expected indentation of 10 space characters but found 8 indent
76:11 error Expected indentation of 12 space characters but found 10 indent
76:18 error Gratuitous parentheses around expression no-extra-parens
77:11 error Expected indentation of 12 space characters but found 10 indent
81:7 error Expected indentation of 8 space characters but found 6 indent
82:9 error Expected indentation of 10 space characters but found 8 indent
83:11 error Gratuitous parentheses around expression no-extra-parens
84:11 error Gratuitous parentheses around expression no-extra-parens
85:11 error Gratuitous parentheses around expression no-extra-parens
86:11 error Gratuitous parentheses around expression no-extra-parens
88:11 error Expected indentation of 12 space characters but found 10 indent
91:9 error Expected indentation of 10 space characters but found 8 indent
92:11 error Gratuitous parentheses around expression no-extra-parens
93:11 error Gratuitous parentheses around expression no-extra-parens
94:11 error Gratuitous parentheses around expression no-extra-parens
96:11 error Expected indentation of 12 space characters but found 10 indent
99:9 error Expected indentation of 10 space characters but found 8 indent
100:11 error Expected indentation of 12 space characters but found 10 indent
101:11 error Expected indentation of 12 space characters but found 10 indent
102:10 error Missing semicolon semi
105:1 error Line 105 exceeds the maximum line length of 80 max-len
105:7 error Expected indentation of 8 space characters but found 6 indent
114:5 error Expected indentation of 6 space characters but found 4 indent
115:7 error Expected indentation of 8 space characters but found 6 indent
120:9 error Expected indentation of 10 space characters but found 8 indent
123:7 error Expected indentation of 8 space characters but found 6 indent
126:9 error Expected indentation of 10 space characters but found 8 indent
130:7 error Expected indentation of 8 space characters but found 6 indent
139:5 error Expected indentation of 6 space characters but found 4 indent
140:7 error Expected indentation of 8 space characters but found 6 indent
141:9 error Expected indentation of 10 space characters but found 8 indent
146:7 error Expected indentation of 8 space characters but found 6 indent
154:5 error Expected indentation of 6 space characters but found 4 indent
156:7 error Expected indentation of 8 space characters but found 6 indent
158:7 error Expected indentation of 8 space characters but found 6 indent
159:7 error Expected indentation of 8 space characters but found 6 indent
160:7 error Expected indentation of 8 space characters but found 6 indent
161:7 error Expected indentation of 8 space characters but found 6 indent
162:7 error Expected indentation of 8 space characters but found 6 indent
165:7 error Expected indentation of 8 space characters but found 6 indent
168:7 error Expected indentation of 8 space characters but found 6 indent
170:7 error Expected indentation of 8 space characters but found 6 indent
171:7 error Expected indentation of 8 space characters but found 6 indent
173:7 error Expected indentation of 8 space characters but found 6 indent
176:7 error Expected indentation of 8 space characters but found 6 indent
177:9 error Expected indentation of 10 space characters but found 8 indent
178:9 error Expected indentation of 10 space characters but found 8 indent
189:5 error Expected indentation of 6 space characters but found 4 indent
190:7 error Expected indentation of 8 space characters but found 6 indent
191:7 error Expected indentation of 8 space characters but found 6 indent
192:7 error Expected indentation of 8 space characters but found 6 indent
193:7 error Expected indentation of 8 space characters but found 6 indent
194:7 error Expected indentation of 8 space characters but found 6 indent
195:7 error Expected indentation of 8 space characters but found 6 indent
198:7 error Expected indentation of 8 space characters but found 6 indent
199:9 error Expected indentation of 10 space characters but found 8 indent
200:9 error Expected indentation of 10 space characters but found 8 indent
201:9 error Expected indentation of 10 space characters but found 8 indent
202:9 error Expected indentation of 10 space characters but found 8 indent
204:9 error Expected indentation of 10 space characters but found 8 indent
205:9 error Expected indentation of 10 space characters but found 8 indent
206:9 error Expected indentation of 10 space characters but found 8 indent
207:9 error Expected indentation of 10 space characters but found 8 indent
211:7 error Expected indentation of 8 space characters but found 6 indent
212:9 error Expected indentation of 10 space characters but found 8 indent
216:7 error Expected indentation of 8 space characters but found 6 indent
217:9 error Expected indentation of 10 space characters but found 8 indent
218:9 error Expected indentation of 10 space characters but found 8 indent
219:9 error Expected indentation of 10 space characters but found 8 indent
220:9 error Expected indentation of 10 space characters but found 8 indent
221:9 error Expected indentation of 10 space characters but found 8 indent
222:9 error Expected indentation of 10 space characters but found 8 indent
223:9 error Expected indentation of 10 space characters but found 8 indent
224:9 error Expected indentation of 10 space characters but found 8 indent
233:5 error Expected indentation of 6 space characters but found 4 indent
235:7 error Expected indentation of 8 space characters but found 6 indent
236:9 error Expected indentation of 10 space characters but found 8 indent
241:9 error Expected indentation of 10 space characters but found 8 indent
245:7 error Expected indentation of 8 space characters but found 6 indent
254:5 error Expected indentation of 6 space characters but found 4 indent
256:7 error Expected indentation of 8 space characters but found 6 indent
257:9 error Expected indentation of 10 space characters but found 8 indent
262:9 error Expected indentation of 10 space characters but found 8 indent
266:7 error Expected indentation of 8 space characters but found 6 indent
275:5 error Expected indentation of 6 space characters but found 4 indent
276:7 error Expected indentation of 8 space characters but found 6 indent
279:7 error Unexpected 'todo' comment no-warning-comments
280:7 error Expected indentation of 8 space characters but found 6 indent
281:9 error Expected indentation of 10 space characters but found 8 indent
282:9 error Expected indentation of 10 space characters but found 8 indent
286:7 error Expected indentation of 8 space characters but found 6 indent
287:7 error Expected indentation of 8 space characters but found 6 indent
288:7 error Expected indentation of 8 space characters but found 6 indent
290:1 error Line 290 exceeds the maximum line length of 80 max-len
290:7 error Expected indentation of 8 space characters but found 6 indent
291:7 error Expected indentation of 8 space characters but found 6 indent
292:1 error Line 292 exceeds the maximum line length of 80 max-len
292:9 error Expected indentation of 10 space characters but found 8 indent
295:7 error Expected indentation of 8 space characters but found 6 indent
297:9 error Expected indentation of 10 space characters but found 8 indent
304:9 error Expected indentation of 10 space characters but found 8 indent
305:11 error Expected indentation of 12 space characters but found 10 indent
306:11 error Expected indentation of 12 space characters but found 10 indent
307:11 error Expected indentation of 12 space characters but found 10 indent
311:9 error Expected indentation of 10 space characters but found 8 indent
312:11 error Expected indentation of 12 space characters but found 10 indent
313:11 error Expected indentation of 12 space characters but found 10 indent
314:11 error Expected indentation of 12 space characters but found 10 indent
320:3 error Expected indentation of 4 space characters but found 2 indent
322:5 error Expected indentation of 6 space characters but found 4 indent
325:5 error Expected indentation of 6 space characters but found 4 indent
✖ 135 problems (135 errors, 0 warnings)
Technically, scroll duration and easing method are UA defined so we can’t truly polyfill this. My opinion is that a smart default would be to have the scroll time be proportional to the distance between scroll start and scroll end with a min and max on the number of steps it will take to get there. A step is defined as one animation frame at 60fps.
Is there a callback when reached target?
Should be included for completeness, and is also a breaking changes from v0.2.1
According to http://dev.w3.org/csswg/cssom-view/#scrolloptions, the scroll methods take a ScrollOptions
object as the 2nd arg, not a string:
element.scrollIntoView(true, {x: 10, y: 10, behavior: 'smooth'});
I'm aware that this is a polyfil and not a library so it doesn't add any additional features or parameters, so I know I'm kinda of contradicting myself by asking... but I was wondering if there has been any discussion of the possibility of adding an offset to the scrollIntoView()
method? Or if anyone knows if this is something that vendors will be adding to the core functionality to all scroll methods in the future?
I know there's obviously numerous ways you can get this working, for example getting the elements y
position and applying the offset to it and using scrollTo();
instead, but it would be nice if it's possible to scroll the element into view with say 20px offset before the element with scrollIntoView()
, like so:
document.querySelector('.hello').scrollIntoView({ top: -=20, behavior: 'smooth' });
Using the -=
to just modify the already gotten y
value of top
and adding/subtracting the offset value. Not requesting it as a feature or anything, just looking for some extra input or alternative ideas to see what people think :)
We need better solution of dependency management, please.
And the name https://www.npmjs.com/package/smoothscroll is already taken, maybe try another.
Hi Dustan, sadly I've redesigned my personal site a while ago and it's not longer using this script. I've seen it's present in the README (jeremenichelli.github.io/site) so I think you should remove it. If you want I can help you build an example page.
Cheers!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.