✏️ 正在编辑: main.js
路径:
/home/h359620/public_html/wp-content/themes/datis/assets/js/main.js
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
document.addEventListener('DOMContentLoaded', () => { const scroller = document.querySelector('.d-overfolw-x'); const btn = document.getElementById('stepsNext'); if (!scroller || !btn) return; const getSlides = () => Array.from(scroller.children).filter(el => el.nodeType === 1); const step = () => { const slides = getSlides(); return (slides[0]?.getBoundingClientRect().width) || scroller.getBoundingClientRect().width; }; const goNextLoop = () => { const slides = getSlides(); if (!slides.length) return; const maxScroll = scroller.scrollWidth - scroller.clientWidth; const s = step(); if (scroller.scrollLeft >= maxScroll) { scroller.scrollTo({ left: 0, behavior: 'smooth' }); return; } scroller.scrollBy({ left: -s, behavior: 'smooth' }); }; const onClick = (e) => { e.preventDefault(); e.stopPropagation(); goNextLoop(); }; btn.addEventListener('click', onClick, { passive: false }); btn.addEventListener('touchend', onClick, { passive: false }); }); document.addEventListener('DOMContentLoaded', () => { (function () { function isRTL(el) { // 1) dir روی html/body یا نزدیکترین والد const dirAttr = (el && el.closest && el.closest('[dir]') && el.closest('[dir]').getAttribute('dir')) || document.documentElement.getAttribute('dir') || ''; if (String(dirAttr).toLowerCase() === 'rtl') return true; // 2) computed style try { return window.getComputedStyle(el).direction === 'rtl'; } catch (e) { return false; } } function setFill(starsEl, value, max) { value = Math.max(0, Math.min(max, value)); const pct = (value / max) * 100; starsEl.style.setProperty('--fill', pct + '%'); starsEl.setAttribute('aria-valuenow', String(value)); } function valueFromPointer(starsEl, clientX) { const rect = starsEl.getBoundingClientRect(); let x = Math.max(0, Math.min(rect.width, clientX - rect.left)); const wrap = starsEl.closest('.datis-rating'); const max = parseInt(wrap?.dataset.max || '5', 10); // ✅ FIX: اگر RTL بود از راست حساب کن if (isRTL(starsEl)) { x = rect.width - x; } const v = Math.ceil((x / rect.width) * max); return Math.max(1, Math.min(max, v)); } document.addEventListener('click', function (e) { const starsEl = e.target.closest('.datis-stars-ui'); if (!starsEl) return; const wrap = starsEl.closest('.datis-rating'); if (!wrap) return; const max = parseInt(wrap.dataset.max || '5', 10); const v = valueFromPointer(starsEl, e.clientX); const input = wrap.querySelector('#datis_rating'); const number = wrap.querySelector('#datis_rating_number'); if (input) input.value = String(v); if (number) number.textContent = String(v); setFill(starsEl, v, max); }); // ✅ فقط همین یکی کافیست (DOMContentLoaded داخلی حذف شد) document.querySelectorAll('.datis-rating').forEach(wrap => { const starsEl = wrap.querySelector('.datis-stars-ui'); const input = wrap.querySelector('#datis_rating'); const number = wrap.querySelector('#datis_rating_number'); const max = parseInt(wrap.dataset.max || '5', 10); const v = parseFloat(input?.value || '0') || 0; if (number) number.textContent = String(v); if (starsEl) setFill(starsEl, v, max); }); })(); }); document.addEventListener("DOMContentLoaded", function () { if (typeof Swiper === "undefined") return; const swiperEl = document.querySelector(".datis-latest-projects-swiper"); if (!swiperEl) return; const demo = swiperEl.getAttribute("data-demo") || ""; const isArchitecture = demo === "architecture"; // ---- Navigation elements (scoped) ---- const navNext = isArchitecture ? swiperEl.querySelector(".latest-projects-next") : swiperEl.querySelector(".swiper-button-next"); const navPrev = isArchitecture ? swiperEl.querySelector(".latest-projects-prev") : swiperEl.querySelector(".swiper-button-prev"); // ---- Swiper init ---- // نکته: برای فیلتر شدن صحیح، در architecture loop را خاموش میکنیم const swiper = new Swiper(swiperEl, { loop: isArchitecture ? false : true, spaceBetween: 20, speed: 600, // ✅ فقط در architecture دو اسلاید نمایش بده slidesPerView: isArchitecture ? 1 : 0.8, breakpoints: isArchitecture ? { 576: { slidesPerView: 2 }, 992: { slidesPerView: 2 }, // فقط 2 تا در دسکتاپ هم } : { 576: { slidesPerView: 2 }, 992: { slidesPerView: 2.6 }, }, navigation: { nextEl: navNext, prevEl: navPrev, }, }); // ---- Filters only in architecture ---- if (!isArchitecture) return; const filtersWrap = document.querySelector(".datis-recent-projects-filters"); if (!filtersWrap) return; const slides = Array.from(swiperEl.querySelectorAll(".swiper-slide")); filtersWrap.addEventListener("click", function (e) { const btn = e.target.closest(".projects-filter"); if (!btn) return; const term = btn.getAttribute("data-term"); // active class filtersWrap .querySelectorAll(".projects-filter") .forEach((b) => b.classList.remove("is-active")); btn.classList.add("is-active"); // filter slides slides.forEach((slide) => { const attr = slide.getAttribute("data-terms") || ""; const terms = attr.split(",").map((x) => x.trim()).filter(Boolean); const show = term === "all" || terms.includes(String(term)); slide.style.display = show ? "" : "none"; }); // update swiper (برای display:none بهتره اینها رو هم صدا بزنیم) swiper.update(); swiper.updateSlides(); swiper.updateProgress(); swiper.updateSlidesClasses(); swiper.slideTo(0, 0); }); }); document.addEventListener('DOMContentLoaded', function () { if (typeof Swiper === 'undefined') return; new Swiper('.datis-latest-blog-swiper', { loop: false, spaceBetween: 24, speed: 600, watchOverflow: true, slidesPerView: 1.2, breakpoints: { 576: { slidesPerView: 1 }, 768: { slidesPerView: 2 }, 992: { slidesPerView: 3 } // ✅ مثل پروژهها: 2.5 }, navigation: { nextEl: '.datis-latest-blog-swiper .swiper-button-next', prevEl: '.datis-latest-blog-swiper .swiper-button-prev', }, pagination: { el: '.datis-latest-blog-swiper .swiper-pagination', clickable: true } }); }); document.addEventListener('click', function (e) { const catBtn = e.target.closest('.sidebar-categories .categories-btn'); if (catBtn) { const box = catBtn.closest('.sidebar-categories'); catBtn.toggleAttribute('open'); const list = box.querySelector('.categories'); if (list) list.toggleAttribute('hidden'); return; } const sortBtn = e.target.closest('.sidebar-sorting .sorting-btn'); if (sortBtn) { const box = sortBtn.closest('.sidebar-sorting'); sortBtn.toggleAttribute('open'); const list = box.querySelector('.sorting'); if (list) list.toggleAttribute('hidden'); return; } const statusBtn = e.target.closest('.sidebar-project-status .status-btn'); if (statusBtn) { const box = statusBtn.closest('.sidebar-project-status'); statusBtn.toggleAttribute('open'); const list = box.querySelector('.status'); if (list) list.toggleAttribute('hidden'); return; } const dateBtn = e.target.closest('.sidebar-project-date .date-btn'); if (dateBtn) { const box = dateBtn.closest('.sidebar-project-date'); dateBtn.toggleAttribute('open'); const list = box.querySelector('.date'); if (list) list.toggleAttribute('hidden'); return; } }); document.querySelectorAll('.search-tab').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.search-tab').forEach(b => b.classList.remove('is-active')); btn.classList.add('is-active'); }); }); (function () { const MAX_MOVE = 22; // شدت حرکت px (مثلا 18 تا 30 خوبه) const MAX_ROT = 4; // چرخش خیلی کم (deg) اگر نمیخوای: 0 const EASE = 0.22; // سرعت رسیدن به هدف (0.15 نرمتر، 0.28 سریعتر) function initContainer(container) { const layers = Array.from(container.querySelectorAll('.animate-image')); if (!layers.length) return; // لایهلایه: اولی کم حرکت، آخری بیشتر const weights = layers.map((_, i) => { if (layers.length === 1) return 1; return 0.6 + (i / (layers.length - 1)) * 0.8; // 0.6..1.4 }); let tx = 0, ty = 0, rx = 0, ry = 0; let cx = 0, cy = 0, crx = 0, cry = 0; let raf = null; function render() { cx += (tx - cx) * EASE; cy += (ty - cy) * EASE; crx += (rx - crx) * EASE; cry += (ry - cry) * EASE; layers.forEach((el, i) => { const w = weights[i]; const x = cx * w; const y = cy * w; // چرخش خیلی ریز (اختیاری) const rX = crx * (w * 0.35); const rY = cry * (w * 0.35); el.style.transform = `translate3d(${x.toFixed(2)}px, ${y.toFixed(2)}px, 0)` + (MAX_ROT ? ` rotateX(${rX.toFixed(2)}deg) rotateY(${rY.toFixed(2)}deg)` : ''); }); if ( Math.abs(tx - cx) > 0.05 || Math.abs(ty - cy) > 0.05 || Math.abs(rx - crx) > 0.05 || Math.abs(ry - cry) > 0.05 ) { raf = requestAnimationFrame(render); } else { raf = null; } } function onMove(e) { const r = container.getBoundingClientRect(); const nx = ((e.clientX - r.left) / r.width - 0.5) * 2; // -1..1 const ny = ((e.clientY - r.top) / r.height - 0.5) * 2; // -1..1 tx = nx * MAX_MOVE; ty = ny * MAX_MOVE; rx = -ny * MAX_ROT; ry = nx * MAX_ROT; if (!raf) raf = requestAnimationFrame(render); } function onLeave() { tx = ty = rx = ry = 0; if (!raf) raf = requestAnimationFrame(render); } container.addEventListener('mousemove', onMove); container.addEventListener('mouseleave', onLeave); } document.querySelectorAll('.datis-container').forEach(initContainer); })(); document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll(".js-back-button").forEach(function (btn) { btn.addEventListener("click", function (e) { e.preventDefault(); if (document.referrer && document.referrer !== location.href) { window.location.href = document.referrer; } else { window.history.back(); } }); }); }); document.addEventListener("DOMContentLoaded", function () { document .querySelectorAll(".architecture-demo .heading p") .forEach((p) => { const text = p.textContent.trim(); if (!text) return; const parts = text.split(" "); if (parts.length < 2) return; p.innerHTML = `<b class="first-word">${parts.shift()}</b> ` + parts.join(" "); }); }); (function () { function showHeader() { document.documentElement.classList.add("styles-ready"); } function waitForStylesheets() { const links = document.querySelectorAll('link[rel="stylesheet"]'); if (!links.length) { showHeader(); return; } let loaded = 0; const total = links.length; function checkDone() { loaded++; if (loaded >= total) { showHeader(); } } links.forEach(link => { // If already loaded (from cache) if (link.sheet) { checkDone(); } else { link.addEventListener("load", checkDone); link.addEventListener("error", checkDone); } }); } // Run after DOM is ready document.addEventListener("DOMContentLoaded", waitForStylesheets); })();
💾 保存文件
← 返回文件管理器