Derzeit implementieren wir auf meinem Modal Focus Trapping aus Gründen der Barrierefreiheit. Meine Fokusfalle verhindert, dass der Benutzer außerhalb des Modals mit der Tabulatortaste bewegt. Wenn er beim letzten Element die Tabulatortaste drückt, wird das erste fokussiert, und durch Umschalten der Tabulatortaste beim ersten wird das letzte fokussiert. Hier ist mein Problem zum ersten Mal aufgefallen.
In meiner Funktionskomponente für das Modal habe ich einen useEffect. Dieser useEffect erkennt, wenn Änderungen vorgenommen werden, führt zu einem erneuten Rendern (unter Verwendung eines benutzerdefinierten Hooks) und greift dann auf einen Verweis aller interagierbaren Elemente zu. Dies wird dann an eine Funktion namens focusTrap übergeben.
Benutzerdefinierter Hook useIsMount (wird zur Überprüfung verwendet, ob sich DOM beim ersten oder zweiten Rendern befindet, falls Elemente nicht zum Referenzieren bereit sind):
Code: Select all
export const useIsMount = () => {
const isMountRef = useRef(true);
useEffect(() => {
isMountRef.current = false;
}, []);
return isMountRef.current;
};
Code: Select all
useEffectCode: Select all
const isMount = useIsMount();
useEffect(() => {
if (!isMount) {
const buttonsElement = buttonsRef?.current;
buttonsElement && focusTrap(buttonsElement, onClose);
}
});
Code: Select all
!isMountMeine focusTrap-Funktion, die mich bisher noch nicht im Stich gelassen hat:
Code: Select all
export const focusTrap = (modalElement, onClose) => {
const focusableElements = modalElement.querySelectorAll(
'button, [href], input, checkbox, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
const handleTabKeyPress = (event) => {
if (event.key === "Tab") {
if (event.shiftKey && document.activeElement === firstElement) {
event.preventDefault();
lastElement.focus();
} else if (!event.shiftKey && document.activeElement === lastElement) {
event.preventDefault();
firstElement.focus();
}
}
};
const handleEscapeKeyPress = (event) => {
if (event.key === "Escape") {
onClose();
}
};
modalElement.addEventListener("keydown", handleTabKeyPress, true);
modalElement.addEventListener("keydown", handleEscapeKeyPress);
return () => {
modalElement.removeEventListener("keydown", handleTabKeyPress, true);
modalElement.removeEventListener("keydown", handleEscapeKeyPress);
};
};

Ich habe versucht:
- Leeres Abhängigkeitsarray hinzufügen (Fängt das erneute Rendern von Inhaltsänderungen nicht ab, erkennt die Download-Schaltfläche nicht)
- Hinzufügen eines Abhängigkeitsarrays für isMount und totalEdits/(Verfolgen Sie die Bearbeitungs-/Löschbeträge, um die Download-Schaltfläche zu rendern), aber ich rufe trotzdem focusTrap auf, da ich eine if-Anweisung benötige, um festzustellen, ob es Änderungen gibt
Code: Select all
totalDeletesCode: Select all
if (totalEdits > 0 || totalDeletes > 0) { buttonsElement && focusTrap(buttonsElement, onClose); } - Eine Menge anderer Dinge, an die ich mich zu diesem Zeitpunkt ehrlich gesagt noch nicht einmal erinnern kann. Entweder schlägt die Fokusfalle fehl und entkommt dem Modal (erkennt aber die neue Schaltfläche!) oder die Schaltfläche ist immer noch nicht fokussierbar
Wäre es irgendwie möglich, eine laufende Funktion zu beenden, bevor sie erneut ausgeführt wird?
Wenn ich diese Schaltfläche schließlich an einer bedingten Stelle rendere, an der sie nicht das letzte Element ist, ist sie gut fokussiert (wie vor der Schaltfläche „Bestätigen“). FocusTrap wird jedoch immer noch mehrmals ausgeführt, und das ist nicht gut.
Mobile version