2026-10-22 22:51:04 +08:00

124 lines
8.4 KiB
JavaScript

(function () {
'use strict';
var mobile = document.getElementById('mobileMenuBtn');
var navMenu = document.querySelector('.nav-menu');
var navRight = document.querySelector('.nav-right');
var mobileViewport = window.matchMedia('(max-width: 768px)');
var navItems = [];
function setNavOpen(item, open) {
if (open) navItems.forEach(function (other) { if (other !== item) setNavOpen(other, false); });
item.dropdown.classList.toggle('active', open);
item.link.setAttribute('aria-expanded', String(open));
}
function closeNavMenus() { navItems.forEach(function (item) { setNavOpen(item, false); }); }
function setMobileOpen(open) {
if (navMenu) navMenu.classList.toggle('active', open);
if (navRight) navRight.classList.toggle('active', open);
if (mobile) mobile.setAttribute('aria-expanded', String(open));
if (!open) closeNavMenus();
}
document.querySelectorAll('.nav-menu > div > a').forEach(function (link) {
var dropdown = link.parentElement.querySelector('.nav-cont');
if (!dropdown) return;
var item = { link: link, dropdown: dropdown, parent: link.parentElement };
navItems.push(item);
dropdown.id = 'static-nav-dropdown-' + navItems.length;
link.setAttribute('aria-controls', dropdown.id);
setNavOpen(item, false);
link.addEventListener('click', function (event) {
event.preventDefault();
var toggle = mobileViewport.matches || event.detail === 0;
setNavOpen(item, !toggle || link.getAttribute('aria-expanded') !== 'true');
});
link.addEventListener('keydown', function (event) {
if (event.key === ' ' || event.key === 'ArrowDown') {
event.preventDefault();
setNavOpen(item, event.key === 'ArrowDown' || link.getAttribute('aria-expanded') !== 'true');
var first = dropdown.querySelector('a[href]');
if (event.key === 'ArrowDown' && first) first.focus();
}
});
item.parent.addEventListener('mouseenter', function () { if (!mobileViewport.matches) setNavOpen(item, true); });
item.parent.addEventListener('mouseleave', function () { if (!mobileViewport.matches && !item.parent.contains(document.activeElement)) setNavOpen(item, false); });
item.parent.addEventListener('focusout', function (event) {
var next = event.relatedTarget;
if (!item.parent.contains(next) && (!mobileViewport.matches || !navMenu.contains(next))) setNavOpen(item, false);
});
});
if (mobile) {
mobile.setAttribute('role', 'button'); mobile.tabIndex = 0;
mobile.setAttribute('aria-expanded', 'false');
if (navMenu) { navMenu.id = 'static-nav-menu'; mobile.setAttribute('aria-controls', navMenu.id); }
mobile.addEventListener('click', function () { setMobileOpen(!navMenu.classList.contains('active')); });
mobile.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); mobile.click(); }
});
}
document.addEventListener('click', function (event) { if (navMenu && !navMenu.contains(event.target) && !mobile?.contains(event.target)) closeNavMenus(); });
document.addEventListener('keydown', function (event) {
if (event.key !== 'Escape') return;
var open = navItems.find(function (item) { return item.link.getAttribute('aria-expanded') === 'true'; });
if (open) { closeNavMenus(); open.link.focus(); }
else if (mobileViewport.matches && navMenu?.classList.contains('active')) { setMobileOpen(false); mobile?.focus(); }
});
mobileViewport.addEventListener('change', function () { setMobileOpen(false); });
document.querySelectorAll('.language-selected').forEach(function (button) {
button.setAttribute('role', 'button'); button.tabIndex = 0; button.setAttribute('aria-haspopup', 'true');
function toggle(event) { event.stopPropagation(); button.closest('.language-selector').classList.toggle('active'); }
button.addEventListener('click', toggle);
button.addEventListener('keydown', function (event) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); toggle(event); } });
});
document.addEventListener('click', function () { document.querySelectorAll('.language-selector.active').forEach(function (element) { element.classList.remove('active'); }); });
if (window.Swiper) document.querySelectorAll('.swiper, .swiper-container').forEach(function (element) {
if (element.swiper || !element.querySelector('.swiper-wrapper')) return;
var count = element.querySelectorAll('.swiper-slide').length;
new window.Swiper(element, { loop: count > 1, speed: 550, autoplay: count > 1 ? { delay: 6000, disableOnInteraction: false } : false, pagination: { el: element.querySelector('.swiper-pagination'), clickable: true }, navigation: { nextEl: element.querySelector('.swiper-button-next'), prevEl: element.querySelector('.swiper-button-prev') } });
});
document.querySelectorAll('.country-item').forEach(function (item) {
item.addEventListener('click', function () {
var siblings = Array.from(item.parentElement.children); var index = siblings.indexOf(item);
siblings.forEach(function (sibling) { sibling.classList.toggle('active', sibling === item); });
item.parentElement.parentElement.querySelectorAll('.hot-list').forEach(function (list, i) { list.classList.toggle('active', i === index); });
});
});
document.querySelectorAll('[data-local-filter]').forEach(function (input) {
input.addEventListener('input', function () {
var query = input.value.toLowerCase().trim();
document.querySelectorAll('[data-filter-row]').forEach(function (row) { row.hidden = query && !row.textContent.toLowerCase().includes(query); });
});
});
var search = document.getElementById('document-input');
var searchButton = document.querySelector('.input-search .search-btn');
if (search && searchButton) {
function navigateSearch() { var target = new URL(search.dataset.results || 'document-result.html', location.href); target.searchParams.set('search', search.value.trim()); location.href = target.href; }
searchButton.setAttribute('role', 'button'); searchButton.tabIndex = 0;
searchButton.addEventListener('click', navigateSearch);
search.addEventListener('keydown', function (event) { if (event.key === 'Enter') { event.preventDefault(); navigateSearch(); } });
}
var searchData = document.getElementById('static-search-data');
var results = document.getElementById('static-search-results');
var queryInput = document.getElementById('static-search-query');
if (searchData && results && queryInput) {
var data = JSON.parse(searchData.textContent); var params = new URLSearchParams(location.search); queryInput.value = params.get('search') || '';
function renderSearch() {
var query = queryInput.value.trim().toLowerCase(); results.replaceChildren();
var found = data.items.filter(function (item) { return !query || (item.title + ' ' + item.text).toLowerCase().includes(query); });
found.forEach(function (item) { var li = document.createElement('li'); var link = document.createElement('a'); link.href = item.href; link.textContent = item.title; li.append(link); results.append(li); });
if (!found.length) { var li = document.createElement('li'); li.textContent = data.empty; results.append(li); }
}
document.getElementById('static-search-form').addEventListener('submit', function (event) { event.preventDefault(); var url = new URL(location.href); url.searchParams.set('search', queryInput.value.trim()); history.replaceState(null, '', url); renderSearch(); });
queryInput.addEventListener('input', renderSearch); renderSearch();
}
document.querySelectorAll('.static-article img, .practice img').forEach(function (img) {
img.style.cursor = 'zoom-in'; img.addEventListener('click', function () {
var dialog = document.createElement('dialog'); dialog.className = 'static-lightbox';
var close = document.createElement('button'); close.type = 'button'; close.setAttribute('aria-label', document.documentElement.lang === 'en' ? 'Close' : '关闭'); close.textContent = '\u00d7';
var picture = document.createElement('img'); picture.src = img.src; picture.alt = img.alt;
dialog.append(close, picture); document.body.append(dialog); close.addEventListener('click', function () { dialog.close(); });
dialog.addEventListener('click', function (event) { if (event.target === dialog) dialog.close(); });
dialog.addEventListener('close', function () { dialog.remove(); }); dialog.showModal();
});
});
})();