From 2639406ae25d57db238c4e2188f526c750dcfeb8 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Tue, 15 Sep 2020 22:09:03 +0100 Subject: [PATCH] Simulate page load announcement in autofocus JS Screenreaders announce the title of the page when it loads and their users are used to it signifying a new page. By focusing a form control when the page loads, this announcement is replaced with that of the control label. This commit prefixes the label with the page title so it gets announced when the page loads, notifying screenreader users that they are on a new page. The page title prefix is removed once focus shifts from the form control as its presence in any further announcements could be confusing. --- app/assets/javascripts/autofocus.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/autofocus.js b/app/assets/javascripts/autofocus.js index 002a676a2..4d3d94849 100644 --- a/app/assets/javascripts/autofocus.js +++ b/app/assets/javascripts/autofocus.js @@ -3,13 +3,26 @@ Modules.Autofocus = function() { this.start = function(component) { - var forceFocus = $(component).data('forceFocus'); + var $component = $(component), + forceFocus = $component.data('forceFocus'), + labelText = $('label[for="' + $component.attr('id') + '"]').eq(0).text().trim(), + clearAriaLabel = evt => { + $component.removeAttr('aria-label'); + $component.off('blur', clearAriaLabel); + }; // if the page loads with a scroll position, we can't assume the item to focus onload // is still where users intend to start if (($(window).scrollTop() > 0) && !forceFocus) { return; } - $(component).filter('input, textarea, select').eq(0).trigger('focus'); + // screenreaders announce the page title when a new page loads + // this will be lost when focus is moved to our form control so add it to the label instead + $component.attr('aria-label', document.title + ' - ' + labelText); + + $component.filter('input, textarea, select').eq(0).trigger('focus'); + + // the page title prefix is only needed on page load so remove once focus has shifted + $component.on('blur', clearAriaLabel); }; };