PageSourceSearch

https://cjwilliam.com/wholesale/wp-content/themes/stablos-child/js/components/custom-header.js?ver=1.4.3

js cjwilliam.com collected 2026-10-05 19:12:27 UTC 3,610 bytes, 90 lines download raw bytes

1/**
2 * CJW custom header — mobile drawer + jewelry submenu toggle.
3 * Desktop submenu is pure CSS (:hover / :focus-within); no JS needed.
4 */
5(function () {
6    var burger = document.querySelector('.cjw-header__burger');
7    var drawer = document.getElementById('cjw-drawer');
8    if (!burger || !drawer) return;
9
10    var backdrop = drawer.querySelector('.cjw-drawer__backdrop');
11    var closeBtn = drawer.querySelector('.cjw-drawer__close');
12
13    function openDrawer() {
14        drawer.classList.add('is-open');
15        drawer.setAttribute('aria-hidden', 'false');
16        burger.setAttribute('aria-expanded', 'true');
17        document.body.classList.add('cjw-drawer-open');
18    }
19
20    function closeDrawer() {
21        drawer.classList.remove('is-open');
22        drawer.setAttribute('aria-hidden', 'true');
23        burger.setAttribute('aria-expanded', 'false');
24        document.body.classList.remove('cjw-drawer-open');
25    }
26
27    burger.addEventListener('click', openDrawer);
28    if (closeBtn) closeBtn.addEventListener('click', closeDrawer);
29    if (backdrop) backdrop.addEventListener('click', closeDrawer);
30
31    document.addEventListener('keydown', function (e) {
32        if (e.key === 'Escape' && drawer.classList.contains('is-open')) {
33            closeDrawer();
34        }
35    });
36
37    // Close drawer on link click (but not group toggles)
38    drawer.querySelectorAll('a').forEach(function (a) {
39        a.addEventListener('click', closeDrawer);
40    });
41
42    // Jewelry group toggle (inline collapse)
43    drawer.querySelectorAll('.cjw-drawer__group-toggle').forEach(function (btn) {
44        btn.addEventListener('click', function () {
45            var expanded = btn.getAttribute('aria-expanded') === 'true';
46            var listId = btn.getAttribute('aria-controls');
47            var list = listId ? document.getElementById(listId) : null;
48            btn.setAttribute('aria-expanded', expanded ? 'false' : 'true');
49            if (list) {
50                if (expanded) list.setAttribute('hidden', '');
51                else list.removeAttribute('hidden');
52            }
53        });
54    });
55
56    // Desktop submenu — click on parent toggles the submenu instead of navigating.
57    // Sub-links (Natural / Lab Diamonds) handle the real navigation. Hover still
58    // works for mouse users via CSS.
59    document.querySelectorAll('.cjw-nav__item--has-submenu').forEach(function (item) {
60        var toggle = item.querySelector('.cjw-nav__toggle');
61        if (!toggle) return;
62
63        toggle.addEventListener('click', function (e) {
64            e.preventDefault();
65            var open = item.classList.toggle('is-open');
66            toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
67        });
68    });
69
70    // Close any open desktop submenu when clicking outside.
71    document.addEventListener('click', function (e) {
72        document.querySelectorAll('.cjw-nav__item--has-submenu.is-open').forEach(function (item) {
73            if (!item.contains(e.target)) {
74                item.classList.remove('is-open');
75                var t = item.querySelector('.cjw-nav__toggle');
76                if (t) t.setAttribute('aria-expanded', 'false');
77            }
78        });
79    });
80
81    // Close on Escape.
82    document.addEventListener('keydown', function (e) {
83        if (e.key !== 'Escape') return;
84        document.querySelectorAll('.cjw-nav__item--has-submenu.is-open').forEach(function (item) {
85            item.classList.remove('is-open');
86            var t = item.querySelector('.cjw-nav__toggle');
87            if (t) t.setAttribute('aria-expanded', 'false');
88        });
89    });
90})();

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.