مدیاویکی:Common.js: تفاوت میان نسخهها
Esfandiari (بحث | مشارکتها) بدون خلاصۀ ویرایش |
Esfandiari (بحث | مشارکتها) بدون خلاصۀ ویرایش |
||
| خط ۴٬۶۱۴: | خط ۴٬۶۱۴: | ||
render(''); | render(''); | ||
}); | }); | ||
/* | |||
Faraghaib / فراغیب | |||
Paste this file into: MediaWiki:Common.js | |||
Vanilla JavaScript; no external library or framework is required. | |||
*/ | |||
(function () { | |||
"use strict"; | |||
function toPersianNumber(value) { | |||
return String(value).replace(/\d/g, function (digit) { | |||
return "۰۱۲۳۴۵۶۷۸۹"[digit]; | |||
}); | |||
} | |||
function initCounter(counter) { | |||
if (counter.dataset.fgCounterReady === "true") { | |||
return; | |||
} | |||
counter.dataset.fgCounterReady = "true"; | |||
var target = Number(counter.getAttribute("data-fg-count")) || 0; | |||
var suffix = counter.getAttribute("data-fg-suffix") || ""; | |||
var duration = 1100; | |||
var start = null; | |||
function frame(timestamp) { | |||
if (start === null) { | |||
start = timestamp; | |||
} | |||
var progress = Math.min((timestamp - start) / duration, 1); | |||
var eased = 1 - Math.pow(1 - progress, 3); | |||
var current = Math.round(target * eased); | |||
counter.textContent = toPersianNumber(current) + suffix; | |||
if (progress < 1) { | |||
window.requestAnimationFrame(frame); | |||
} | |||
} | |||
window.requestAnimationFrame(frame); | |||
} | |||
function initCounters(root) { | |||
var counters = root.querySelectorAll("[data-fg-count]"); | |||
if (!counters.length) { | |||
return; | |||
} | |||
if (!("IntersectionObserver" in window)) { | |||
counters.forEach(initCounter); | |||
return; | |||
} | |||
var observer = new IntersectionObserver(function (entries, currentObserver) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
initCounter(entry.target); | |||
currentObserver.unobserve(entry.target); | |||
} | |||
}); | |||
}, { threshold: 0.4 }); | |||
counters.forEach(function (counter) { | |||
observer.observe(counter); | |||
}); | |||
} | |||
function initReveal(root) { | |||
var elements = root.querySelectorAll(".fg-reveal"); | |||
if (!elements.length || !("IntersectionObserver" in window)) { | |||
return; | |||
} | |||
elements.forEach(function (element) { | |||
element.classList.add("fg-reveal--pending"); | |||
}); | |||
var observer = new IntersectionObserver(function (entries, currentObserver) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
entry.target.classList.add("fg-reveal--visible"); | |||
currentObserver.unobserve(entry.target); | |||
} | |||
}); | |||
}, { threshold: 0.12 }); | |||
elements.forEach(function (element) { | |||
observer.observe(element); | |||
}); | |||
} | |||
function initSlider(slider) { | |||
if (slider.dataset.fgSliderReady === "true") { | |||
return; | |||
} | |||
var slides = Array.prototype.slice.call(slider.querySelectorAll(".fg-slide")); | |||
var dots = Array.prototype.slice.call(slider.querySelectorAll(".fg-slider__dot")); | |||
var previous = slider.querySelector(".fg-slider__button--prev"); | |||
var next = slider.querySelector(".fg-slider__button--next"); | |||
if (!slides.length || !dots.length) { | |||
return; | |||
} | |||
var activeIndex = 0; | |||
var timer = null; | |||
var reducedMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches; | |||
slider.dataset.fgSliderReady = "true"; | |||
slider.classList.add("fg-slider--ready"); | |||
function show(index) { | |||
activeIndex = (index + slides.length) % slides.length; | |||
slides.forEach(function (slide, slideIndex) { | |||
var active = slideIndex === activeIndex; | |||
slide.classList.toggle("is-active", active); | |||
slide.setAttribute("aria-hidden", active ? "false" : "true"); | |||
}); | |||
dots.forEach(function (dot, dotIndex) { | |||
var active = dotIndex === activeIndex; | |||
dot.classList.toggle("is-active", active); | |||
dot.setAttribute("aria-selected", active ? "true" : "false"); | |||
dot.setAttribute("tabindex", active ? "0" : "-1"); | |||
}); | |||
} | |||
function stop() { | |||
if (timer !== null) { | |||
window.clearInterval(timer); | |||
timer = null; | |||
} | |||
} | |||
function start() { | |||
if (reducedMotion || document.hidden || timer !== null) { | |||
return; | |||
} | |||
timer = window.setInterval(function () { | |||
show(activeIndex + 1); | |||
}, 6200); | |||
} | |||
if (previous) { | |||
previous.addEventListener("click", function () { | |||
show(activeIndex - 1); | |||
stop(); | |||
start(); | |||
}); | |||
} | |||
if (next) { | |||
next.addEventListener("click", function () { | |||
show(activeIndex + 1); | |||
stop(); | |||
start(); | |||
}); | |||
} | |||
dots.forEach(function (dot, index) { | |||
dot.addEventListener("click", function () { | |||
show(index); | |||
stop(); | |||
start(); | |||
}); | |||
dot.addEventListener("keydown", function (event) { | |||
if (event.key === "ArrowLeft" || event.key === "ArrowRight") { | |||
event.preventDefault(); | |||
show(activeIndex + (event.key === "ArrowLeft" ? 1 : -1)); | |||
dots[activeIndex].focus(); | |||
stop(); | |||
start(); | |||
} | |||
}); | |||
}); | |||
slider.addEventListener("mouseenter", stop); | |||
slider.addEventListener("mouseleave", start); | |||
slider.addEventListener("focusin", stop); | |||
slider.addEventListener("focusout", function (event) { | |||
if (!slider.contains(event.relatedTarget)) { | |||
start(); | |||
} | |||
}); | |||
document.addEventListener("visibilitychange", function () { | |||
if (document.hidden) { | |||
stop(); | |||
} else { | |||
start(); | |||
} | |||
}); | |||
show(0); | |||
start(); | |||
} | |||
function init(root) { | |||
var container = root && root.jquery ? root[0] : root; | |||
var home = container && container.querySelector ? container.querySelector(".fg-home") : null; | |||
if (!home) { | |||
return; | |||
} | |||
home.querySelectorAll(".fg-slider").forEach(initSlider); | |||
initCounters(home); | |||
initReveal(home); | |||
} | |||
if (window.mw && window.mw.hook) { | |||
window.mw.hook("wikipage.content").add(init); | |||
} else { | |||
document.addEventListener("DOMContentLoaded", function () { | |||
init(document); | |||
}); | |||
} | |||
}()); | |||