feat(navigation): hard-switch to Zibll navigation and Font Awesome 5

This commit is contained in:
kate522 committed 2026-08-18 20:46:21 +08:00
1 parent 3c3ddac8be
commit a0b84977a2
630 files changed
+101647 -11293

No files matched your search

+1 -198
View File
@@ -6,20 +6,15 @@
* aksrt.confirm(msg, opts) — i18n confirm dialog
* aksrt.scrollTopTo(target, off) — smart scroll with header offset
* aksrt.loading(el, show) — element-level loading overlay
* aksrt.Drawer(opts) — mobile fullscreen drawer + route
* aksrt.route(url, title) — push/replace URL + title
*
* Declarative interactions (event delegation on body):
* [data-toggle-class] — toggle class on target
* [data-close] — close target element
* [data-onclick] — trigger click on another element
* [data-confirm] — confirm before action
* [data-action] — universal AJAX action button (like/follow/checkin)
* [ajax-action] — general AJAX button with modal response
*
* Body scroll direction bus:
* body.scroll-down / body.scroll-up (threshold 100px)
*
* @package AKSRT
* @since 5.0.0
*/
@@ -194,70 +189,6 @@
el.appendChild(mask);
};
// ══════════════════════════════════════════════════════════════
// §10.11 — Drawer: mobile fullscreen slide-in + route
// ══════════════════════════════════════════════════════════════
aksrt.Drawer = function (opts) {
opts = opts || {};
var drawerEl = document.createElement('div');
drawerEl.className = 'aksrt-drawer' + (opts.class ? ' ' + opts.class : '');
drawerEl.innerHTML =
'<div class="aksrt-drawer__header">' +
'<button type="button" class="aksrt-drawer__back"><i class="fas fa-arrow-left"></i></button>' +
'<span class="aksrt-drawer__title">' + escapeHtml(opts.title || '') + '</span>' +
'</div>' +
'<div class="aksrt-drawer__body"></div>';
var body = drawerEl.querySelector('.aksrt-drawer__body');
if (opts.content) {
body.innerHTML = opts.content;
} else if (opts.remote) {
aksrt.loading(body, true);
fetch(opts.remote, { credentials: 'same-origin' })
.then(function (r) { return r.text(); })
.then(function (html) {
aksrt.loading(body, false);
body.innerHTML = html;
if (window.AksrtFrontend) AksrtFrontend.rehydrate(body, 'drawer');
})
.catch(function () { aksrt.loading(body, false); });
}
document.body.appendChild(drawerEl);
document.body.classList.add('drawer-open');
requestAnimationFrame(function () { drawerEl.classList.add('is-open'); });
if (opts.route) {
aksrt.route(opts.route, opts.title);
}
function close() {
drawerEl.classList.remove('is-open');
document.body.classList.remove('drawer-open');
setTimeout(function () { drawerEl.remove(); }, 300);
if (opts.route) {
window.history.back();
}
if (typeof opts.onClose === 'function') opts.onClose();
}
drawerEl.querySelector('.aksrt-drawer__back').addEventListener('click', close);
// minitouch right-swipe close
if (window.aksrt.minitouch) {
aksrt.minitouch(drawerEl, {
direction: 'right',
onEnd: close
});
}
return { el: drawerEl, body: body, close: close };
};
// ══════════════════════════════════════════════════════════════
// §10.11 — route: tab route + popstate
// ══════════════════════════════════════════════════════════════
@@ -292,59 +223,12 @@
});
});
// ══════════════════════════════════════════════════════════════
// §10.2 — Unified body scroll direction bus
// ══════════════════════════════════════════════════════════════
var _lastScrollTop = 0;
var _scrollTicking = false;
var SCROLL_BUS_THRESHOLD = 100;
function updateScrollBus() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var body = document.body;
if (scrollTop > SCROLL_BUS_THRESHOLD) {
body.classList.add('body-scroll');
} else {
body.classList.remove('body-scroll');
}
if (scrollTop > _lastScrollTop + 10) {
body.classList.add('scroll-down');
body.classList.remove('scroll-up');
} else if (scrollTop < _lastScrollTop - 10) {
body.classList.remove('scroll-down');
body.classList.add('scroll-up');
}
_lastScrollTop = Math.max(0, scrollTop);
_scrollTicking = false;
}
window.addEventListener('scroll', function () {
if (!_scrollTicking) {
_scrollTicking = true;
requestAnimationFrame(updateScrollBus);
}
}, { passive: true });
// ══════════════════════════════════════════════════════════════
// §10.11 — Declarative interactions (event delegation)
// ══════════════════════════════════════════════════════════════
document.addEventListener('click', function (e) {
var target = e.target.closest('[data-toggle-class]');
if (target) {
e.preventDefault();
var cls = target.getAttribute('data-toggle-class');
var sel = target.getAttribute('data-target') || target.getAttribute('data-toggle-target');
var el = sel ? document.querySelector(sel) : target;
if (el && cls) el.classList.toggle(cls);
return;
}
target = e.target.closest('[data-close]');
var target = e.target.closest('[data-close]');
if (target) {
e.preventDefault();
var sel2 = target.getAttribute('data-close');
@@ -616,16 +500,6 @@
});
});
// Swiper re-init
if (typeof Swiper !== 'undefined') {
root.querySelectorAll('[data-swiper-config]:not(.swiper-initialized)').forEach(function (el) {
try {
var cfg = JSON.parse(el.dataset.swiperConfig || '{}');
new Swiper(el, cfg);
} catch (ex) { /* */ }
});
}
// Countdowns
root.querySelectorAll('[data-countdown]').forEach(function (el) {
if (el.dataset.countdownBound) return;
@@ -642,76 +516,6 @@
});
};
// ══════════════════════════════════════════════════════════════
// §10.11 — minitouch: general direction gesture
// ══════════════════════════════════════════════════════════════
aksrt.minitouch = function (el, opts) {
opts = opts || {};
var direction = opts.direction || 'any';
var startX = 0, startY = 0, currentX = 0, currentY = 0;
var active = false;
el.addEventListener('touchstart', function (e) {
if (e.touches.length !== 1) return;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
currentX = startX;
currentY = startY;
active = true;
if (typeof opts.onStart === 'function') {
var stop = opts.onStart({ x: startX, y: startY, el: el });
if (stop === false) active = false;
}
}, { passive: true });
el.addEventListener('touchmove', function (e) {
if (!active) return;
currentX = e.touches[0].clientX;
currentY = e.touches[0].clientY;
var dx = currentX - startX;
var dy = currentY - startY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 10) return;
var angle = Math.atan2(dy, dx) * 180 / Math.PI;
var dir = getDirection(angle);
if (direction !== 'any' && dir !== direction) {
if (typeof opts.stop === 'function' && opts.stop({ direction: dir, dx: dx, dy: dy })) {
active = false;
return;
}
}
if (typeof opts.onIng === 'function') {
opts.onIng({ dx: dx, dy: dy, direction: dir, distance: dist, el: el });
}
}, { passive: true });
el.addEventListener('touchend', function () {
if (!active) return;
active = false;
var dx = currentX - startX;
var dy = currentY - startY;
var dist = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx) * 180 / Math.PI;
var dir = getDirection(angle);
if (typeof opts.onEnd === 'function') {
opts.onEnd({ dx: dx, dy: dy, direction: dir, distance: dist, el: el });
}
}, { passive: true });
};
function getDirection(angle) {
if (angle >= -45 && angle < 45) return 'right';
if (angle >= 45 && angle < 135) return 'bottom';
if (angle >= -135 && angle < -45) return 'top';
return 'left';
}
// ══════════════════════════════════════════════════════════════
// Helpers
// ══════════════════════════════════════════════════════════════
@@ -728,7 +532,6 @@
// ── DOMContentLoaded ──
function initRuntime() {
updateScrollBus();
aksrt.autoFun(document);
}