Merge pull request 'fix(nav): stop dual overflow folders fighting on insertBefore' (#261) from worktree-fix-checkoverflow-insertbefore into main

Reviewed-on: CYL/wordpress-theme-aksrt#261
This commit is contained in:
2026-07-22 19:28:54 +08:00
2 changed files with 43 additions and 87 deletions
+39 -10
View File
@@ -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 =
'<a href="javascript:void(0);"><i class="fas fa-bars" aria-hidden="true"></i></a><ul class="sub-menu"></ul>';
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);
}
+4 -77
View File
@@ -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 =
'<button type="button" class="aksrt-nav-more__btn" aria-haspopup="true" aria-expanded="false">更多 <i class="fas fa-caret-down"></i></button>' +
'<ul class="aksrt-nav-more__dropdown"></ul>';
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();
});
})();