Twenty Twenty: Replace Smooth Scroll JS implementation with scroll-behavior
CSS property.
The JS implementation had multiple issues and did not work as expected. This change includes an accessibility enhancement by using `prefers-reduced-motion: reduce` media query property for users that don't want motion effects. For further explanation on this media query, see MDN documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior#Accessibility_concerns Props audrasjb, melchoyce, joostdevalk, Anlino, mauteri, sergiomdgomes, littlebigthing, williampatton, netweb, andraganescu, joyously, acosmin, mukesh27, hareesh-pillai. Merges [46824] to the 5.3 branch. Fixes #48763, #48551, #48866. git-svn-id: https://develop.svn.wordpress.org/branches/5.3@46825 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
d0c1415415
commit
5485536237
@ -322,98 +322,6 @@ twentytwenty.intrinsicRatioVideos = {
|
|||||||
|
|
||||||
}; // twentytwenty.instrinsicRatioVideos
|
}; // twentytwenty.instrinsicRatioVideos
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------------------------
|
|
||||||
Smooth Scroll
|
|
||||||
--------------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
twentytwenty.smoothScroll = {
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
// Scroll to anchor
|
|
||||||
this.scrollToAnchor();
|
|
||||||
|
|
||||||
// Scroll to element
|
|
||||||
this.scrollToElement();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Scroll to anchor
|
|
||||||
scrollToAnchor: function() {
|
|
||||||
var anchorElements = document.querySelectorAll( 'a[href*="#"]' );
|
|
||||||
var anchorElementsList = Array.prototype.slice.call( anchorElements );
|
|
||||||
anchorElementsList.filter( function( element ) {
|
|
||||||
if ( element.href === '#' || element.href === '#0' || element.id === 'cancel-comment-reply-link' || element.classList.contains( 'do-not-scroll' ) || element.classList.contains( 'skip-link' ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} ).forEach( function( element ) {
|
|
||||||
element.addEventListener( 'click', function( event ) {
|
|
||||||
var target, scrollOffset, originalOffset, adminBar, scrollSpeed, additionalOffset;
|
|
||||||
|
|
||||||
// On-page links
|
|
||||||
if ( window.location.hostname === event.target.hostname ) {
|
|
||||||
// Figure out element to scroll to
|
|
||||||
target = window.location.hash !== '' && document.querySelector( window.location.hash );
|
|
||||||
target = target ? target : event.target.hash !== '' && document.querySelector( event.target.hash );
|
|
||||||
|
|
||||||
// Does a scroll target exist?
|
|
||||||
if ( target ) {
|
|
||||||
// Only prevent default if animation is actually gonna happen
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// Get options
|
|
||||||
additionalOffset = event.target.dataset.additionalOffset;
|
|
||||||
scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500;
|
|
||||||
|
|
||||||
// Determine offset
|
|
||||||
|
|
||||||
adminBar = document.querySelector( '#wpadminbar' );
|
|
||||||
|
|
||||||
originalOffset = target.getBoundingClientRect().top + window.pageYOffset;
|
|
||||||
scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset;
|
|
||||||
|
|
||||||
if ( adminBar && event.target.className === 'to-the-top' ) {
|
|
||||||
scrollOffset = scrollOffset - adminBar.getBoundingClientRect().height;
|
|
||||||
}
|
|
||||||
|
|
||||||
twentytwentyScrollTo( scrollOffset, null, scrollSpeed );
|
|
||||||
|
|
||||||
window.location.hash = event.target.hash.slice( 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
},
|
|
||||||
|
|
||||||
// Scroll to element
|
|
||||||
scrollToElement: function() {
|
|
||||||
var scrollToElement = document.querySelector( '*[data-scroll-to]' );
|
|
||||||
|
|
||||||
if ( scrollToElement ) {
|
|
||||||
scrollToElement.addEventListener( 'click', function( event ) {
|
|
||||||
var originalOffset, additionalOffset, scrollOffset, scrollSpeed,
|
|
||||||
// Figure out element to scroll to
|
|
||||||
target = event.target.dataset.twentytwentyScrollTo;
|
|
||||||
|
|
||||||
// Make sure said element exists
|
|
||||||
if ( target ) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// Get options
|
|
||||||
additionalOffset = event.target.dataset.additionalOffset;
|
|
||||||
scrollSpeed = event.target.dataset.scrollSpeed ? event.target.dataset.scrollSpeed : 500;
|
|
||||||
|
|
||||||
// Determine offset
|
|
||||||
originalOffset = target.getBoundingClientRect().top + window.pageYOffset;
|
|
||||||
scrollOffset = additionalOffset ? originalOffset + additionalOffset : originalOffset;
|
|
||||||
|
|
||||||
twentytwentyScrollTo( scrollOffset, null, scrollSpeed );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // twentytwenty.smoothScroll
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------------------------
|
||||||
Modal Menu
|
Modal Menu
|
||||||
--------------------------------------------------------------------------------------------------- */
|
--------------------------------------------------------------------------------------------------- */
|
||||||
@ -745,7 +653,6 @@ twentytwentyDomReady( function() {
|
|||||||
twentytwenty.toggles.init(); // Handle toggles
|
twentytwenty.toggles.init(); // Handle toggles
|
||||||
twentytwenty.coverModals.init(); // Handle cover modals
|
twentytwenty.coverModals.init(); // Handle cover modals
|
||||||
twentytwenty.intrinsicRatioVideos.init(); // Retain aspect ratio of videos on window resize
|
twentytwenty.intrinsicRatioVideos.init(); // Retain aspect ratio of videos on window resize
|
||||||
twentytwenty.smoothScroll.init(); // Smooth scroll to anchor link or a specific element
|
|
||||||
twentytwenty.modalMenu.init(); // Modal Menu
|
twentytwenty.modalMenu.init(); // Modal Menu
|
||||||
twentytwenty.primaryMenu.init(); // Primary Menu
|
twentytwenty.primaryMenu.init(); // Primary Menu
|
||||||
twentytwenty.touchEnabled.init(); // Add class to body if device is touch-enabled
|
twentytwenty.touchEnabled.init(); // Add class to body if device is touch-enabled
|
||||||
@ -891,49 +798,3 @@ function twentytwentyFindParents( target, query ) {
|
|||||||
|
|
||||||
return parents;
|
return parents;
|
||||||
}
|
}
|
||||||
|
|
||||||
// twentytwentyEaseInOutQuad functions http://goo.gl/5HLl8
|
|
||||||
function twentytwentyEaseInOutQuad( t, b, c, d ) {
|
|
||||||
t /= d / 2;
|
|
||||||
if ( t < 1 ) {
|
|
||||||
return ( ( ( c / 2 ) * t ) * t ) + b;
|
|
||||||
}
|
|
||||||
t--;
|
|
||||||
return ( ( -c / 2 ) * ( ( t * ( t - 2 ) ) - 1 ) ) + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
function twentytwentyScrollTo( to, callback, duration ) {
|
|
||||||
var start, change, increment, currentTime;
|
|
||||||
|
|
||||||
function move( amount ) {
|
|
||||||
document.documentElement.scrollTop = amount;
|
|
||||||
document.body.parentNode.scrollTop = amount;
|
|
||||||
document.body.scrollTop = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop;
|
|
||||||
change = to - start;
|
|
||||||
increment = 20;
|
|
||||||
currentTime = 0;
|
|
||||||
|
|
||||||
duration = ( typeof ( duration ) === 'undefined' ) ? 500 : duration;
|
|
||||||
|
|
||||||
function animateScroll() {
|
|
||||||
var val;
|
|
||||||
|
|
||||||
// increment the time
|
|
||||||
currentTime += increment;
|
|
||||||
// find the value with the quadratic in-out twentytwentyEaseInOutQuad function
|
|
||||||
val = twentytwentyEaseInOutQuad( currentTime, start, change, duration );
|
|
||||||
// move the document.body
|
|
||||||
move( val );
|
|
||||||
// do the animation unless its over
|
|
||||||
if ( currentTime < duration ) {
|
|
||||||
window.requestAnimationFrame( animateScroll );
|
|
||||||
} else if ( callback && typeof ( callback ) === 'function' ) {
|
|
||||||
// the animation is done so lets callback
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
animateScroll();
|
|
||||||
}
|
|
||||||
|
@ -115,6 +115,13 @@ blockquote::after {
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: 62.5%; /* 1rem = 10px */
|
font-size: 62.5%; /* 1rem = 10px */
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
html {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -115,6 +115,13 @@ blockquote::after {
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: 62.5%; /* 1rem = 10px */
|
font-size: 62.5%; /* 1rem = 10px */
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
html {
|
||||||
|
scroll-behavior: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
Loading…
Reference in New Issue
Block a user