simplr-smoothscroll
simplr-smoothscroll copied to clipboard
Smooth scroll is broken in Chrome 61
Chrome has shipped smooth scrolling for a number of releases now. And in release 61 the scrolling element is no longer the body but the documentElement as specified in the CSS spec.
When this plugin is used it checks the user agent and assumes the scrolling element is the body if it has AppleWebKit in it (which Chrome does).
Ultimately smoothscrolling should be disabled in Chrome as the native platform does it itself. Or if you really wish to control scrolling yourself you should use the document.scrollingElement as the target of the scroll (if the node is defined).
Something like
target = document.scrollingElement ? document.scrollingElement : e("body");
Some resources for the above:
- Announcement for Smooth Scrolling in Chrome from Jan 2016
- Details on the change in scrollTop behavior
- Chromium bug tracking that sites using simplr-smoothscroll are now unable to scroll in Chrome.
This SmoothScroll is not work in Chrome as before. Any news?
I'm for detecting the Chrome's version using navigator.appVersion
and disable the extension for versions above 61.
Hi! I juste fixed the bug on our project with this function, which I added on top of the plugin file.:
function isChrome61OrMore(){
var ua = navigator.userAgent, tem, M = ua.match(/(chrome(?=\/))\/?\s*(\d+)/i) || [];
if(M[1] === 'Chrome' && ua.match(/\bOPR|Edge\/(\d+)/) != null) return false; // Opera
M = M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
if((tem = ua.match(/version\/(\d+)/i))!= null) M.splice(1,1,tem[1]);
return (M[0] == "Chrome" && M[1] >= 61) ? true : false;
}
This line needs to be changed:
var target = (self.target.selector == 'body')
? ((navigator.userAgent.indexOf('AppleWebKit') !== -1 && !isChrome61OrMore()) ? self.target : $('html'))
: container;
And that's it! I hope this can help other people or even maybe be some plugin update? Thanks to previous contributors without whose comments I would never have found this solution.
That code looks like it will break for Opera when they move up to version 61 of blink.
Not good.
Why not change this to be based on document.scrollingElement instead?
Something like: target: (document.scrollingElement ? document.scrollingElement : $('body')),
Then you can avoid the user agent checks.
@dtapuska Your comment is interesting and you are right, there is already a problem with Opera 48.
As you might not know, I am very new to web development, so any advice is precious to me. Could you maybe explain a bit more about your solution?
If I remember well, I tried it yesterday without success, but I maybe missed something. I would be really happy to produce a better fix.
So the document.scrollingElement was added and it provides a quick selection of what scrolling element is (can be document or body depending on what mode the document is in).
Basically it is an alias. If it is defined (it isn't available in old browsers so you need to check for its existence). If it is set you should always use it as the target and not use any of the logic based on the user agent.
Fortunately most browsers that have shipped in the past few years have this feature. And so in say Chrome 60 document.scrollingElement == document.body but in Chrome 61 document.scrollingElement == document.documentElement
Thanks a lot for your explanations! I think I now understand. This is indeed a way better solution, which I will try tomorrow morning as soon as I get to work. You did the magic, baby junior web dev is growing ;-)
I just tried and found where to implement your solution. There was still a problem with .stop(), but I think I found a way. Our website now works on all browsers I have on my computer.
Here, I modified the original condition (navigator.userAgent.indexOf('AppleWebKit') !== -1 ) ? self.target : $('html')
to (document.scrollingElement) ? document.scrollingElement : document.documentElement
Like this:
var target = (self.target.selector == 'body') ? ((document.scrollingElement) ? document.scrollingElement : document.documentElement) : container;
And added the condition if(target != document.documentElement)
on the mousewheel event:
if(target != document.documentElement){ self.target.mousewheel(function (event, delta) { wheel = true; if (delta < 0) top = (top+viewport) >= self.target.outerHeight(true) ? top : top += step; else top = top <= 0 ? 0 : top -= step; target.stop().animate({scrollTop: top}, self.speed, self.ease, function () { wheel = false; }); return false; }); }
@dtapuska What do you think about this fix?
I think self.target in fact is wrong.. and it really should be document.scrollingElement but I'm not a javascript wizard at all. Perhaps @simov can comment.
Smooth scroll v1.0 not working in chrome newer version 61.x. I have found another github solution Smooth scroll v2.2.0 which solve scroll issue on chome. https://github.com/kswedberg/jquery-smooth-scroll
simply updated version of smoothscroll.
Thank you!!! It solved my problem.
My prestashop theme has this library and it's been a bit difficult to find a solution with so many libraries until I have found this post
Thanks Minivio! On first try it didn't work. I'm an idiot - WPRocket was caching.
After clearing all cache, your fix worked like a charm.
Thanks!
@minivio Forked this with your fix here : https://github.com/Shagshag/simplr-smoothscroll
Is this liable to a push into beta anytime soon?
not working on Chrome 70