keep focus when setting "location.hash" on tabs navigation

Setting the location hash property routes the focus to the new hash
value, so, to make the focus stay on the tab and avoid the scroll
movement, let's use window.history instead of location.hash

closes LS-2792, LS-2791
flag= remember_settings_tab

Test plan

- Go to a course setting page
- Move around the tabs using the arrows keys
- Expect the focus to stay in the tab after releasing the key
- Expect not to see any scroll movement when switching tabs
- Repeat the test for the account settings page

Change-Id: Ic81a9305c7c6861f010aa157554be471d5ec04cd
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/278385
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Jonathan Guardado <jonathan.guardado@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
QA-Review: Ed Schiebel <eschiebel@instructure.com>
This commit is contained in:
Jonathan Guardado 2021-11-15 19:25:39 -06:00
parent 242dcd18ce
commit b28d3872d0
2 changed files with 28 additions and 10 deletions

View File

@ -60,16 +60,21 @@ export function addUsersLink(event) {
}
$(document).ready(function () {
const settingsTabs = document
.getElementById('account_settings_tabs')
?.querySelectorAll('ul>li>a[id^="tab"]')
// find the index of tab whose id matches the URL's hash
const initialTab =
ENV.FEATURES && ENV.FEATURES.remember_settings_tab
? Array.from(
document
.getElementById('account_settings_tabs')
?.querySelectorAll('ul>li>a[id^="tab"]') || []
).findIndex(t => `#${t.id}` === `${window.location.hash}-link`)
? Array.from(settingsTabs || []).findIndex(t => `#${t.id}` === `${window.location.hash}-link`)
: -1
if (ENV.FEATURES && ENV.FEATURES.remember_settings_tab && !window.location.hash) {
// Sync the location hash with window.history, this fixes some issues with the browser back
// button when going back to or from the settings tab
const defaultTab = settingsTabs[0]?.href
window.history.replaceState(null, null, defaultTab)
}
function checkFutureListingSetting() {
if ($('#account_settings_restrict_student_future_view_value').is(':checked')) {
$('.future_listing').show()
@ -151,7 +156,10 @@ $(document).ready(function () {
$('#account_settings_tabs').on('tabsactivate', (event, ui) => {
try {
const hash = new URL(ui.newTab.context.href).hash
window.location.hash = hash
if (window.location.hash !== hash) {
window.history.pushState(null, null, hash)
}
ui.newTab.focus(0)
} catch (_ignore) {
// get here if `new URL` throws, but it shouldn't, and
// there's really nothing we need to do about it

View File

@ -168,15 +168,25 @@ $(document).ready(function () {
$tabBar = $('#course_details_tabs')
if (ENV.FEATURES && ENV.FEATURES.remember_settings_tab) {
const settingsTabs = $tabBar[0].querySelectorAll('ul>li>a[href*="#tab"]')
// find the index of the tab whose href matches the URL's hash
const initialTab = Array.from(
$tabBar[0].querySelectorAll('ul>li>a[href*="#tab"]') || []
).findIndex(t => `#${t.id}` === `${window.location.hash}-link`)
const initialTab = Array.from(settingsTabs || []).findIndex(
t => `#${t.id}` === `${window.location.hash}-link`
)
// Sync the location hash with window.history, this fixes some issues with the browser back
// button when going back to or from the details tab
if (!window.location.hash) {
const defaultTab = settingsTabs[0]?.href
window.history.replaceState(null, null, defaultTab)
}
$tabBar
.on('tabsactivate', (event, ui) => {
try {
const hash = new URL(ui.newTab.context.href).hash
window.location.hash = hash
if (window.location.hash !== hash) {
window.history.pushState(null, null, hash)
}
ui.newTab.focus(0)
} catch (_ignore) {
// if the URL can't be parsed, so be it.
}