diff --git a/assets/js/core/nav.js b/assets/js/core/nav.js index b773f568..3b9936e3 100644 --- a/assets/js/core/nav.js +++ b/assets/js/core/nav.js @@ -18,16 +18,42 @@ } function clearFolding() { - var more = document.querySelector(".navbar-nav > li.aksrt-nav-more"); - if (!more) return; - var sub = more.querySelector(".sub-menu"); - var nav = more.parentNode; - if (sub && nav) { - while (sub.firstChild) { - nav.insertBefore(sub.firstChild, more); + // Support both zibll-style more and any legacy .aksrt-nav-more nodes. + var mores = document.querySelectorAll(".navbar-nav > li.aksrt-nav-more"); + Array.prototype.forEach.call(mores, function (more) { + var nav = more.parentNode; + if (!nav) { + more.remove(); + return; } - } - more.remove(); + // Prefer direct child .sub-menu (zibll contract); fall back to first matching submenu. + var sub = null; + for (var i = 0; i < more.children.length; i++) { + var child = more.children[i]; + if ( + child.tagName === "UL" && + (child.classList.contains("sub-menu") || + child.classList.contains("aksrt-nav-more__dropdown")) + ) { + sub = child; + break; + } + } + if (!sub) { + sub = more.querySelector(".sub-menu, .aksrt-nav-more__dropdown"); + } + if (sub) { + while (sub.firstChild) { + // Guard: only insertBefore when more is still a child of nav. + if (more.parentNode === nav) { + nav.insertBefore(sub.firstChild, more); + } else { + nav.appendChild(sub.firstChild); + } + } + } + more.remove(); + }); } function navFolding() { @@ -53,6 +79,7 @@ var navsWidth = 66; var foldItems = []; Array.prototype.forEach.call(nav.children, function (li) { + if (li.classList.contains("aksrt-nav-more")) return; navsWidth += li.offsetWidth || 0; if (navsWidth > surplus) foldItems.push(li); }); @@ -63,7 +90,9 @@ more.innerHTML = ''; var sub = more.querySelector(".sub-menu"); - foldItems.forEach(function (li) { sub.appendChild(li); }); + foldItems.forEach(function (li) { + if (li && li.parentNode) sub.appendChild(li); + }); nav.appendChild(more); appendChevrons(more); } diff --git a/assets/js/enhancements.js b/assets/js/enhancements.js index 6bf0bbd0..f12d6c17 100644 --- a/assets/js/enhancements.js +++ b/assets/js/enhancements.js @@ -521,83 +521,11 @@ } /* ============================================================ - * 4. 导航溢出自动折叠 - * 菜单项超出容器宽度时折叠进「更多」下拉 + * 4. 导航溢出折叠 + * 由 assets/js/core/nav.js(zibll 1:1 navFolding)负责。 + * 此处不再重复实现,避免两套逻辑争抢 .aksrt-nav-more 节点 + * 触发 NotFoundError: insertBefore (moreLi 已被对方 remove)。 * ============================================================ */ - function initNavOverflow() { - var nav = document.querySelector('.navbar-top .nav.navbar-nav'); - if (!nav) return; - - // 创建「更多」按钮 - var moreLi = document.createElement('li'); - moreLi.className = 'nav-item aksrt-nav-more'; - moreLi.style.display = 'none'; - moreLi.innerHTML = - '' + - ''; - nav.appendChild(moreLi); - - var moreBtn = moreLi.querySelector('.aksrt-nav-more__btn'); - var dropdown = moreLi.querySelector('.aksrt-nav-more__dropdown'); - - moreBtn.addEventListener('click', function (e) { - e.stopPropagation(); - var open = dropdown.classList.toggle('is-open'); - moreBtn.setAttribute('aria-expanded', open ? 'true' : 'false'); - }); - - document.addEventListener('click', function () { - dropdown.classList.remove('is-open'); - moreBtn.setAttribute('aria-expanded', 'false'); - }); - - function checkOverflow() { - var items = Array.from(nav.children).filter(function (el) { - return !el.classList.contains('aksrt-nav-more'); - }); - - // 重置:把所有项移回原位 - while (dropdown.firstChild) { - var li = dropdown.firstChild; - nav.insertBefore(li, moreLi); - } - moreLi.style.display = 'none'; - - var navWidth = nav.clientWidth; - var moreWidth = 80; // 预留「更多」按钮宽度 - var usedWidth = 0; - var overflowItems = []; - - items.forEach(function (item) { - usedWidth += item.offsetWidth; - if (usedWidth + moreWidth > navWidth) { - overflowItems.push(item); - } - }); - - if (overflowItems.length > 0) { - moreLi.style.display = ''; - overflowItems.forEach(function (item) { - dropdown.appendChild(item); - }); - } - } - - // ResizeObserver 监听(避免 resize 抖动) - if ('ResizeObserver' in window) { - var timer = null; - var ro = new ResizeObserver(function () { - if (timer) clearTimeout(timer); - timer = setTimeout(checkOverflow, 100); - }); - ro.observe(nav); - } else { - window.addEventListener('resize', checkOverflow, { passive: true }); - } - - // 初始检测 - checkOverflow(); - } /* ============================================================ * 初始化入口 @@ -605,7 +533,6 @@ document.addEventListener('DOMContentLoaded', function () { initLightbox(); initScrollDirection(); - initNavOverflow(); }); })();