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. Fixes #48763, #48551, #48866. Built from https://develop.svn.wordpress.org/trunk@46824 git-svn-id: http://core.svn.wordpress.org/trunk@46624 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
f93ee2ca76
commit
0f971e68ec
|
@ -322,98 +322,6 @@ twentytwenty.intrinsicRatioVideos = {
|
|||
|
||||
}; // 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
|
||||
--------------------------------------------------------------------------------------------------- */
|
||||
|
@ -745,7 +653,6 @@ twentytwentyDomReady( function() {
|
|||
twentytwenty.toggles.init(); // Handle toggles
|
||||
twentytwenty.coverModals.init(); // Handle cover modals
|
||||
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.primaryMenu.init(); // Primary Menu
|
||||
twentytwenty.touchEnabled.init(); // Add class to body if device is touch-enabled
|
||||
|
@ -891,49 +798,3 @@ function twentytwentyFindParents( target, query ) {
|
|||
|
||||
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 {
|
||||
font-size: 62.5%; /* 1rem = 10px */
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
@ -115,6 +115,13 @@ blockquote::after {
|
|||
|
||||
html {
|
||||
font-size: 62.5%; /* 1rem = 10px */
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '5.4-alpha-46823';
|
||||
$wp_version = '5.4-alpha-46824';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
|
Loading…
Reference in New Issue