theme: improve keyboard navigation for scrolling #268

This commit is contained in:
Sören Weber 2022-06-06 23:58:00 +02:00
parent ccce323f76
commit ae3ad846cc
No known key found for this signature in database
GPG key ID: 07D17FF580AE7589
3 changed files with 68 additions and 15 deletions

View file

@ -26,7 +26,7 @@
<body class="mobile-support" data-url="/"> <body class="mobile-support" data-url="/">
<div id="body" class="default-animation" style="margin-left:0px;"> <div id="body" class="default-animation" style="margin-left:0px;">
<div id="sidebar-overlay"></div> <div id="sidebar-overlay"></div>
<main id="body-inner" class="chapter"> <main id="body-inner" class="chapter" tabindex="-1">
<div class="flex-block-wrapper"> <div class="flex-block-wrapper">
<h1>{{ T "title-404" }}</h1> <h1>{{ T "title-404" }}</h1>
<p></p> <p></p>

View file

@ -104,7 +104,7 @@
{{- end }} {{- end }}
</div> </div>
</nav> </nav>
<main id="body-inner" class="highlightable{{if .Params.chapter}} chapter{{end}}"> <main id="body-inner" class="highlightable{{if .Params.chapter}} chapter{{end}}" tabindex="-1">
<div class="flex-block-wrapper"> <div class="flex-block-wrapper">
<div id="head-tags"> <div id="head-tags">
{{- partial "tags.html" . }} {{- partial "tags.html" . }}

View file

@ -13,6 +13,11 @@ var touchsupport = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0)
var formelements = 'button, datalist, fieldset, input, label, legend, meter, optgroup, option, output, progress, select, textarea'; var formelements = 'button, datalist, fieldset, input, label, legend, meter, optgroup, option, output, progress, select, textarea';
// PerfectScrollbar
var psc;
var psm;
var pst;
function switchTab(tabGroup, tabId) { function switchTab(tabGroup, tabId) {
allTabItems = jQuery("[data-tab-group='"+tabGroup+"']"); allTabItems = jQuery("[data-tab-group='"+tabGroup+"']");
targetTabItems = jQuery("[data-tab-group='"+tabGroup+"'][data-tab-item='"+tabId+"']"); targetTabItems = jQuery("[data-tab-group='"+tabGroup+"'][data-tab-item='"+tabId+"']");
@ -301,7 +306,6 @@ function initMenuScrollbar(){
return; return;
} }
var content = '#body-inner';
var autofocus = false; var autofocus = false;
document.addEventListener('keydown', function(event){ document.addEventListener('keydown', function(event){
// for initial keyboard scrolling support, no element // for initial keyboard scrolling support, no element
@ -311,30 +315,37 @@ function initMenuScrollbar(){
// it and give focus to the scrollbar - only // it and give focus to the scrollbar - only
// to just remove the focus right after scrolling // to just remove the focus right after scrolling
// happend // happend
var p = document.querySelector(content).matches(':hover'); var c = document.querySelector('#body-inner').matches(':hover');
var m = document.querySelector('#content-wrapper').matches(':hover'); var m = document.querySelector('#content-wrapper').matches(':hover');
var t = document.querySelector('#TableOfContents').matches(':hover');
var f = event.target.matches( formelements ); var f = event.target.matches( formelements );
if( !p && !m && !f ){ if( !c && !m && !t && !f ){
// only do this hack if none of our scrollbars // only do this hack if none of our scrollbars
// is hovered // is hovered
autofocus = true; autofocus = true;
// if we are showing the sidebar as a flyout we // if we are showing the sidebar as a flyout we
// want to scroll the content-wrapper, otherwise we want // want to scroll the content-wrapper, otherwise we want
// to scroll the body // to scroll the body
var n = document.querySelector('body').matches('.sidebar-flyout'); var nt = document.querySelector('body').matches('.toc-flyout');
if( n ){ var nm = document.querySelector('body').matches('.sidebar-flyout');
if( nt ){
pst && pst.scrollbarY.focus();
}
else if( nm ){
psm && psm.scrollbarY.focus(); psm && psm.scrollbarY.focus();
} }
else{ else{
document.querySelector('#body-inner').focus();
psc && psc.scrollbarY.focus(); psc && psc.scrollbarY.focus();
} }
} }
}); });
// scrollbars will install their own keyboard handlers // scrollbars will install their own keyboard handlers
// that need to be executed inbetween our own handlers // that need to be executed inbetween our own handlers
var psm = new PerfectScrollbar('#content-wrapper');
// PSC removed for #242 #243 #244 // PSC removed for #242 #243 #244
var psc; // = new PerfectScrollbar(content); // psc = new PerfectScrollbar('#body-inner');
psm = new PerfectScrollbar('#content-wrapper');
pst = new PerfectScrollbar('#TableOfContents');
document.addEventListener('keydown', function(){ document.addEventListener('keydown', function(){
// if we facked initial scrolling, we want to // if we facked initial scrolling, we want to
// remove the focus to not leave visual markers on // remove the focus to not leave visual markers on
@ -342,12 +353,14 @@ function initMenuScrollbar(){
if( autofocus ){ if( autofocus ){
psc && psc.scrollbarY.blur(); psc && psc.scrollbarY.blur();
psm && psm.scrollbarY.blur(); psm && psm.scrollbarY.blur();
pst && pst.scrollbarY.blur();
autofocus = false; autofocus = false;
} }
}); });
// on resize, we have to redraw the scrollbars to let new height // on resize, we have to redraw the scrollbars to let new height
// affect their size // affect their size
window.addEventListener('resize', function(){ window.addEventListener('resize', function(){
pst && pst.update();
psm && psm.update(); psm && psm.update();
psc && psc.update(); psc && psc.update();
}); });
@ -415,19 +428,53 @@ function initImageStyles(){
}); });
} }
function sidebarEscapeHandler( event ){
if( event.key == "Escape" ){
var b = document.querySelector( 'body' );
b.classList.remove( 'sidebar-flyout' );
document.removeEventListener( 'keydown', sidebarEscapeHandler );
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
}
}
function tocEscapeHandler( event ){
if( event.key == "Escape" ){
var b = document.querySelector( 'body' );
b.classList.remove( 'toc-flyout' );
document.removeEventListener( 'keydown', tocEscapeHandler );
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
}
}
function initToc(){ function initToc(){
function showNav(){ function showNav(){
var b = document.querySelector( 'body' ); var b = document.querySelector( 'body' );
b.classList.toggle( 'sidebar-flyout' ); b.classList.toggle( 'sidebar-flyout' );
var n = b.matches('.sidebar-flyout'); if( b.classList.contains( 'sidebar-flyout' ) ){
if( n ){
b.classList.remove( 'toc-flyout' ); b.classList.remove( 'toc-flyout' );
document.removeEventListener( 'keydown', tocEscapeHandler );
document.addEventListener( 'keydown', sidebarEscapeHandler );
}
else{
document.removeEventListener( 'keydown', sidebarEscapeHandler );
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
} }
} }
function showToc(){ function showToc(){
var b = document.querySelector( 'body' ); var b = document.querySelector( 'body' );
b.classList.toggle( 'toc-flyout' ); b.classList.toggle( 'toc-flyout' );
pst && pst.update(); if( b.classList.contains( 'toc-flyout' ) ){
pst && pst.update();
document.addEventListener( 'keydown', tocEscapeHandler );
}
else{
document.removeEventListener( 'keydown', tocEscapeHandler );
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
}
} }
document.querySelector( '#sidebar-overlay' ).addEventListener( 'click', showNav ); document.querySelector( '#sidebar-overlay' ).addEventListener( 'click', showNav );
@ -435,12 +482,10 @@ function initToc(){
document.querySelector( '#toc-overlay' ).addEventListener( 'click', showToc ); document.querySelector( '#toc-overlay' ).addEventListener( 'click', showToc );
var t = document.querySelector( '#toc-menu' ); var t = document.querySelector( '#toc-menu' );
var p = document.querySelector( '.progress' ); var p = document.querySelector( '.progress' );
var pst;
if( t && p ){ if( t && p ){
// we may not have a toc // we may not have a toc
t.addEventListener( 'click', showToc ); t.addEventListener( 'click', showToc );
p.addEventListener( 'click', showToc ); p.addEventListener( 'click', showToc );
pst = new PerfectScrollbar('#TableOfContents');
} }
} }
@ -468,7 +513,11 @@ function initSwipeHandler(){
else if( diffx > 30 ){ else if( diffx > 30 ){
startx = null; startx = null;
starty = null; starty = null;
document.querySelector( 'body' ).classList.toggle( 'sidebar-flyout' ); var b = document.querySelector( 'body' );
b.classList.remove( 'sidebar-flyout' );
document.removeEventListener( 'keydown', sidebarEscapeHandler );
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
} }
} }
return false; return false;
@ -654,6 +703,10 @@ jQuery(function() {
jQuery('[data-nav-id="' + url + '"]').addClass('visited'); jQuery('[data-nav-id="' + url + '"]').addClass('visited');
} }
} }
// finally give initial focus to allow keyboard scrolling in FF
document.querySelector( '#body-inner' ).focus();
psc && psc.scrollbarY.focus();
}); });
jQuery.extend({ jQuery.extend({