Endprüfung Nachrunde R8: restoreFocus fokussiert mit preventScroll
Ohne die Option springt die Seite beim Zurückgeben des Fokus zum Ziel: bei einer Zeile weit unten in
einer langen Liste zur Meldung oben, und die Person verliert ihre Stelle. restoreFocus ruft jetzt
target.focus({ preventScroll: true }); der Fokus (und damit die Ansage) wandert, die Ansicht bleibt stehen.
Die Attrappe in workersFocus.test.mjs merkt sich die Argumente, ein neuer Test pinnt genau einen Aufruf
mit dieser Option.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7c12cd22a6
commit
c48d1834f4
2 files changed
+13
-2
No files matched your search
@@ -21,10 +21,12 @@ export function activeControl(doc) {
|
||||
const usable = (el) => Boolean(el) && typeof el === 'object' && typeof el.focus === 'function' && el.isConnected !== false && el.disabled !== true
|
||||
|
||||
// Gibt den Fokus an den ersten brauchbaren Kandidaten (eingehängt, nicht gesperrt), falls er verloren ging. Ergebnis: ob fokussiert wurde.
|
||||
// preventScroll: fokussiert focus() ohne die Option, springt die Seite zum Ziel; bei einer Zeile weit unten in einer langen Liste würde sie
|
||||
// zur Meldung oben springen und die Person verlöre ihre Stelle. Der Fokus (und damit die Ansage) wandert, die Ansicht bleibt stehen.
|
||||
export function restoreFocus(doc, candidates) {
|
||||
if (!focusLost(doc)) return false
|
||||
const target = candidates.find(usable)
|
||||
if (!target) return false
|
||||
target.focus()
|
||||
target.focus({ preventScroll: true })
|
||||
return true
|
||||
}
|
||||
@@ -9,7 +9,7 @@ const { activeControl, focusLost, restoreFocus } = await loadModule('src/lib/wor
|
||||
function fakeDoc() {
|
||||
const body = { name: 'body' }
|
||||
const doc = { body, documentElement: { name: 'html' }, activeElement: body }
|
||||
const el = (name, extra = {}) => ({ name, isConnected: true, disabled: false, focusCalls: 0, focus() { this.focusCalls += 1; doc.activeElement = this }, ...extra })
|
||||
const el = (name, extra = {}) => ({ name, isConnected: true, disabled: false, focusCalls: 0, focusArgs: [], focus(...args) { this.focusCalls += 1; this.focusArgs.push(args); doc.activeElement = this }, ...extra })
|
||||
return { doc, body, el }
|
||||
}
|
||||
|
||||
@@ -57,3 +57,12 @@ test('restoreFocus: nimmt den ersten Kandidaten, der noch da und frei ist; greif
|
||||
// Dinge ohne focus() (Attrappen, Textknoten) werden übersprungen
|
||||
assert.equal(restoreFocus(doc, [{ isConnected: true }, 'text', 7, second]), true); assert.equal(doc.activeElement, second)
|
||||
})
|
||||
|
||||
// Die Meldung oben (oder eine Zeile weit unten in einer langen Liste) darf den Fokus bekommen, ohne dass die Seite dorthin springt (Nachrunde R8)
|
||||
test('restoreFocus: fokussiert mit preventScroll, damit die Seite nicht zur Meldung oder Zeile springt', () => {
|
||||
const { doc, el } = fakeDoc()
|
||||
const target = el('meldung')
|
||||
assert.equal(restoreFocus(doc, [target]), true)
|
||||
assert.equal(doc.activeElement, target)
|
||||
assert.deepEqual(target.focusArgs, [[{ preventScroll: true }]]) // genau ein Aufruf, genau diese Option
|
||||
})
|
||||
Reference in new issue
Block a user