PageSourceSearch

https://www.nbme.org/wp-content/themes/Divi-child/assets/search-focus-return.js?ver=5.2.0-20260930053117

js nbme.org collected 2026-10-02 02:36:45 UTC 1,991 bytes, 54 lines download raw bytes

1/**
2 * Search popup focus return (Divi 5 header search)
3 *
4 * When the menu search overlay (.et_pb_menu__search-container) is opened via
5 * the search button and then closed via the close button (or any other
6 * means), Divi drops focus to <body>. For keyboard users that means losing
7 * their place in the navigation. Per WCAG 2.4.3 (Focus Order), focus should
8 * return to the trigger element that opened the overlay.
9 *
10 * Approach: cache the most-recently-activated search-button. When a
11 * MutationObserver sees the container's visibility class change from
12 * visible to hidden, restore focus to that cached trigger.
13 */
14(function () {
15  const TRIGGER_SELECTOR = '.et_pb_menu__search-button';
16  const CONTAINER_SELECTOR = '.et_pb_menu__search-container';
17  const VISIBLE_CLASS = 'et_pb_menu__search-container--visible';
18
19  let lastTrigger = null;
20
21  function rememberTrigger(e) {
22    const trigger = e.target.closest(TRIGGER_SELECTOR);
23    if (trigger) lastTrigger = trigger;
24  }
25
26  function watchContainer(container) {
27    let wasVisible = container.classList.contains(VISIBLE_CLASS);
28    const observer = new MutationObserver(function () {
29      const isVisible = container.classList.contains(VISIBLE_CLASS);
30      if (wasVisible && !isVisible && lastTrigger) {
31        // Defer one frame so Divi finishes any focus changes before we restore.
32        requestAnimationFrame(function () {
33          lastTrigger.focus();
34        });
35      }
36      wasVisible = isVisible;
37    });
38    observer.observe(container, { attributes: true, attributeFilter: ['class'] });
39  }
40
41  function init() {
42    document.addEventListener('click', rememberTrigger);
43    document.addEventListener('keydown', function (e) {
44      if (e.key === 'Enter' || e.key === ' ') rememberTrigger(e);
45    });
46    document.querySelectorAll(CONTAINER_SELECTOR).forEach(watchContainer);
47  }
48
49  if (document.readyState === 'loading') {
50    document.addEventListener('DOMContentLoaded', init);
51  } else {
52    init();
53  }
54})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.