Files
wordpress-theme-aksrt/assets/js/core/scroll.js
T

181 lines
5.7 KiB
JavaScript

/**
* AKSRT Scroll Behaviors — back-to-top, floating buttons, reading progress, nav scroll
*/
(function () {
"use strict";
function initBackToTop() {
var el = document.getElementById("float-back-to-top") || document.getElementById("back-to-top");
if (!el) return;
function onScroll() {
if (window.scrollY > 400) {
el.classList.add("is-visible");
} else {
el.classList.remove("is-visible");
}
}
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
el.addEventListener("click", function (e) {
e.preventDefault();
if (window.aksrt && aksrt.scrollTopTo) {
aksrt.scrollTopTo(0);
} else {
window.scrollTo({ top: 0, behavior: "smooth" });
}
});
}
function initFloatingButtons() {
var wrap = document.getElementById("float-right-btns");
if (!wrap) return;
function debugEnabled() {
return !!(window.aksrtData && aksrtData.debug);
}
function debugLog(message, context, level) {
if (!debugEnabled()) return;
var method = level === "error" ? "error" : (level === "warn" ? "warn" : "log");
console[method]("[AKSRT FloatingButtons] " + message, context || {});
}
function reportDebug(eventName, payload) {
if (!(window.aksrtData && aksrtData.debugLog && aksrtData.ajaxUrl && aksrtData.nonce)) {
return;
}
var body = new URLSearchParams();
body.set("action", "aksrt_frontend_debug");
body.set("nonce", aksrtData.nonce);
body.set("source", "floating_buttons");
body.set("event", eventName);
body.set("page", window.location.href);
if (payload && payload.text) body.set("text", String(payload.text));
if (payload && payload.size) body.set("size", String(payload.size));
if (payload && payload.error) body.set("error", String(payload.error));
fetch(aksrtData.ajaxUrl, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" },
credentials: "same-origin",
body: body.toString()
}).catch(function () {});
}
var scrollTimer = null;
function setHidden(hidden) {
wrap.classList.toggle("is-hidden", !!hidden);
}
function syncFromScrollBus() {
var body = document.body;
if (wrap.classList.contains("scroll-down-hide")) {
setHidden(body.classList.contains("scroll-down"));
}
if (wrap.classList.contains("scrolling-hide")) {
setHidden(true);
window.clearTimeout(scrollTimer);
scrollTimer = window.setTimeout(function () {
if (!body.classList.contains("scroll-down")) setHidden(false);
}, 160);
}
}
window.addEventListener("scroll", function () {
requestAnimationFrame(syncFromScrollBus);
}, { passive: true });
wrap.addEventListener("click", function (event) {
var btn = event.target.closest(".float-btn");
if (!btn) return;
if (btn.getAttribute("href") === "#") {
event.preventDefault();
}
if (btn.hasAttribute("data-action") && btn.getAttribute("data-action") === "toggle-theme") {
event.preventDefault();
if (window.aksrt && typeof aksrt.toggleTheme === "function") {
aksrt.toggleTheme();
} else {
document.documentElement.classList.toggle("dark");
document.body.classList.toggle("dark-theme");
}
}
btn.classList.remove("is-rippling");
window.requestAnimationFrame(function () {
btn.classList.add("is-rippling");
window.setTimeout(function () {
btn.classList.remove("is-rippling");
}, 600);
});
});
}
function initReadingProgress() {
var bar = document.getElementById("reading-progress-global");
if (!bar) return;
function update() {
var doc = document.documentElement;
var scrollable = doc.scrollHeight - window.innerHeight;
var pct = scrollable <= 0 ? 100 : Math.min(100, Math.max(0, (window.scrollY / scrollable) * 100));
bar.style.width = pct + "%";
bar.setAttribute("aria-valuenow", String(Math.round(pct)));
}
window.addEventListener("scroll", update, { passive: true });
window.addEventListener("resize", update, { passive: true });
update();
}
function initNavScrollState() {
var nav = document.querySelector(".site-nav");
var sliderContainer = document.querySelector(".header-components-container");
if (nav && sliderContainer) {
nav.classList.add("nav-transparent");
}
var scrollDownHide = document.body.classList.contains("scroll-down-hide");
var ticking = false;
function update() {
ticking = false;
var body = document.body;
if (nav) {
nav.classList.toggle("is-scrolled", body.classList.contains("body-scroll"));
}
if (nav && scrollDownHide) {
if (body.classList.contains("scroll-down")) {
nav.classList.add("is-hidden");
} else {
nav.classList.remove("is-hidden");
}
}
}
function onScroll() {
if (!ticking) {
window.requestAnimationFrame(update);
ticking = true;
}
}
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll, { passive: true });
update();
}
window.AksrtFrontend.register("aksrt-floating-buttons", function () { initFloatingButtons(); });
window.AksrtFrontend.register("aksrt-back-to-top", function () { initBackToTop(); });
window.AksrtFrontend.register("aksrt-reading-progress", function () { initReadingProgress(); });
window.AksrtFrontend.register("aksrt-nav-scroll-state", function () { initNavScrollState(); });
})();