Initialize the base WordPress theme files, including core template hierarchy (index, page, single, archive, 404), WooCommerce template overrides, and essential asset directories.
319 lines
12 KiB
JavaScript
319 lines
12 KiB
JavaScript
/**
|
||
* Motayeb Theme - Main JavaScript
|
||
* مدیریت تعاملات، حالت تاریک، اسکرول و انیمیشنها
|
||
*/
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
|
||
const html = document.documentElement;
|
||
const body = document.body;
|
||
const header = document.getElementById('header');
|
||
|
||
// ==========================================
|
||
// ۱. مدیریت حالت تاریک (Dark Mode)
|
||
// ==========================================
|
||
function initDarkMode() {
|
||
// بررسی تنظیمات ذخیره شده یا تنظیمات سیستم عامل
|
||
const savedTheme = localStorage.getItem('motayeb-theme');
|
||
if (savedTheme === 'dark') {
|
||
html.classList.add('dark');
|
||
}
|
||
|
||
// اتصال رویداد به دکمه تغییر تم
|
||
const darkBtn = header ? header.querySelector('button[aria-label="حالت تاریک"]') : null;
|
||
if (darkBtn) {
|
||
darkBtn.addEventListener('click', function () {
|
||
html.classList.toggle('dark');
|
||
const isDark = html.classList.contains('dark');
|
||
localStorage.setItem('motayeb-theme', isDark ? 'dark' : 'light');
|
||
});
|
||
}
|
||
}
|
||
|
||
// ==========================================
|
||
// ۲. سایه هدر هنگام اسکرول
|
||
// ==========================================
|
||
function initHeaderScroll() {
|
||
if (!header) return;
|
||
window.addEventListener('scroll', function () {
|
||
if (window.scrollY > 50) {
|
||
header.classList.add('shadow-lg');
|
||
} else {
|
||
header.classList.remove('shadow-lg');
|
||
}
|
||
}, { passive: true });
|
||
}
|
||
|
||
// ==========================================
|
||
// ۳. مدیریت پنل جستجو
|
||
// ==========================================
|
||
function initSearchOverlay() {
|
||
const overlay = document.getElementById('search-overlay');
|
||
if (!overlay) return;
|
||
|
||
const input = overlay.querySelector('.search-field');
|
||
const openBtns = document.querySelectorAll('[aria-label="جستجو"]');
|
||
|
||
// باز کردن
|
||
openBtns.forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
overlay.classList.remove('hidden');
|
||
body.style.overflow = 'hidden'; // قفل اسکرول
|
||
setTimeout(function () { if (input) input.focus(); }, 150);
|
||
});
|
||
});
|
||
|
||
// بستن با کلیک روی بکدراپ
|
||
overlay.addEventListener('click', function (e) {
|
||
if (e.target === overlay) {
|
||
closeSearch();
|
||
}
|
||
});
|
||
}
|
||
|
||
function closeSearch() {
|
||
const overlay = document.getElementById('search-overlay');
|
||
if (overlay) {
|
||
overlay.classList.add('hidden');
|
||
body.style.overflow = ''; // آزاد کردن اسکرول
|
||
}
|
||
}
|
||
|
||
// ==========================================
|
||
// ۴. مدیریت منوی موبایل
|
||
// ==========================================
|
||
function initMobileMenu() {
|
||
const menu = document.getElementById('mobile-menu');
|
||
if (!menu) return;
|
||
|
||
// پیدا کردن دکمه همبرگرری
|
||
const openBtn = header ? header.querySelector('button[aria-label="منوی موبایل"]') : null;
|
||
|
||
// پیدا کردن دکمه ضربدر داخل منو و بکدراپ
|
||
const closeBtn = menu.querySelector('button');
|
||
const backdrop = menu.querySelector('.absolute.inset-0');
|
||
|
||
if (openBtn) {
|
||
openBtn.addEventListener('click', function () {
|
||
menu.classList.remove('hidden');
|
||
body.style.overflow = 'hidden';
|
||
});
|
||
}
|
||
|
||
if (closeBtn) {
|
||
closeBtn.addEventListener('click', closeMobileMenu);
|
||
}
|
||
if (backdrop) {
|
||
backdrop.addEventListener('click', closeMobileMenu);
|
||
}
|
||
}
|
||
|
||
function closeMobileMenu() {
|
||
const menu = document.getElementById('mobile-menu');
|
||
if (menu) {
|
||
menu.classList.add('hidden');
|
||
body.style.overflow = '';
|
||
}
|
||
}
|
||
|
||
// ==========================================
|
||
// ۵. میانبرهای کیبورد
|
||
// ==========================================
|
||
function initKeyboardShortcuts() {
|
||
document.addEventListener('keydown', function (e) {
|
||
// بستن با Escape
|
||
if (e.key === 'Escape') {
|
||
closeSearch();
|
||
closeMobileMenu();
|
||
}
|
||
// باز کردن جستجو با Ctrl+K
|
||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
||
e.preventDefault();
|
||
const overlay = document.getElementById('search-overlay');
|
||
if (overlay) {
|
||
overlay.classList.toggle('hidden');
|
||
if (!overlay.classList.contains('hidden')) {
|
||
body.style.overflow = 'hidden';
|
||
setTimeout(function () {
|
||
const input = overlay.querySelector('.search-field');
|
||
if (input) input.focus();
|
||
}, 150);
|
||
} else {
|
||
body.style.overflow = '';
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// ==========================================
|
||
// ۶. اسکرول نرم برای لینکهای #
|
||
// ==========================================
|
||
function initSmoothScroll() {
|
||
document.querySelectorAll('a[href^="#"]:not([href="#"])').forEach(function (anchor) {
|
||
anchor.addEventListener('click', function (e) {
|
||
const targetId = this.getAttribute('href');
|
||
const targetElement = document.querySelector(targetId);
|
||
|
||
if (targetElement) {
|
||
e.preventDefault();
|
||
closeMobileMenu(); // بستن منو اگر باز بود
|
||
|
||
const headerHeight = header ? header.offsetHeight : 0;
|
||
const elementPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
|
||
const offsetPosition = elementPosition - headerHeight - 20;
|
||
|
||
window.scrollTo({
|
||
top: offsetPosition,
|
||
behavior: 'smooth'
|
||
});
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// ==========================================
|
||
// ۷. انیمیشن هنگام اسکرول (Scroll Reveal)
|
||
// ==========================================
|
||
function initScrollAnimations() {
|
||
const elements = document.querySelectorAll('.animate-slide-up, .animate-fade-in');
|
||
if (elements.length === 0) return;
|
||
|
||
// مخفی کردن اولیه
|
||
elements.forEach(function (el) {
|
||
el.style.opacity = '0';
|
||
el.style.transform = 'translateY(30px)';
|
||
el.style.transition = 'opacity 0.7s cubic-bezier(0.5, 0, 0, 1), transform 0.7s cubic-bezier(0.5, 0, 0, 1)';
|
||
});
|
||
|
||
const observer = new IntersectionObserver(function (entries) {
|
||
entries.forEach(function (entry) {
|
||
if (entry.isIntersecting) {
|
||
entry.target.style.opacity = '1';
|
||
entry.target.style.transform = 'translateY(0)';
|
||
observer.unobserve(entry.target); // توقف مشاهده پس از اجرا
|
||
}
|
||
});
|
||
}, {
|
||
threshold: 0.1,
|
||
rootMargin: '0px 0px -40px 0px'
|
||
});
|
||
|
||
elements.forEach(function (el) {
|
||
observer.observe(el);
|
||
});
|
||
}
|
||
|
||
// ==========================================
|
||
// ۸. سیستم توست (برای استفاده در ووکامرس بعداً)
|
||
// ==========================================
|
||
window.motayebToast = function (message, type) {
|
||
type = type || 'success';
|
||
|
||
// حذف توست قبلی اگر وجود داشت
|
||
const existingToast = document.querySelector('.motayeb-toast-notification');
|
||
if (existingToast) existingToast.remove();
|
||
|
||
var toast = document.createElement('div');
|
||
toast.className = 'motayeb-toast-notification fixed top-24 left-1/2 -translate-x-1/2 z-[100] px-6 py-3 rounded-2xl shadow-2xl text-sm font-semibold text-white flex items-center gap-2 transition-all duration-300';
|
||
|
||
// تنظیم رنگ و آیکون
|
||
if (type === 'success') {
|
||
toast.style.backgroundColor = '#2D5F3F';
|
||
toast.innerHTML = '<iconify-icon icon="lucide:check-circle" width="20"></iconify-icon> ' + message;
|
||
} else if (type === 'error') {
|
||
toast.style.backgroundColor = '#dc2626';
|
||
toast.innerHTML = '<iconify-icon icon="lucide:x-circle" width="20"></iconify-icon> ' + message;
|
||
} else {
|
||
toast.style.backgroundColor = '#8B5A3C';
|
||
toast.innerHTML = '<iconify-icon icon="lucide:info" width="20"></iconify-icon> ' + message;
|
||
}
|
||
|
||
// حالت اولیه (مخفی بالای صفحه)
|
||
toast.style.opacity = '0';
|
||
toast.style.transform = 'translate(-50%, -20px)';
|
||
|
||
body.appendChild(toast);
|
||
|
||
// انیمیشن ورود
|
||
requestAnimationFrame(function () {
|
||
toast.style.opacity = '1';
|
||
toast.style.transform = 'translate(-50%, 0)';
|
||
});
|
||
|
||
// حذف خودکار
|
||
setTimeout(function () {
|
||
toast.style.opacity = '0';
|
||
toast.style.transform = 'translate(-50%, -20px)';
|
||
setTimeout(function () { toast.remove(); }, 300);
|
||
}, 3000);
|
||
};
|
||
|
||
|
||
// ==========================================
|
||
// اجرای تمام توابع
|
||
// ==========================================
|
||
initDarkMode();
|
||
initHeaderScroll();
|
||
initSearchOverlay();
|
||
initMobileMenu();
|
||
initKeyboardShortcuts();
|
||
initSmoothScroll();
|
||
initScrollAnimations();
|
||
|
||
// ==========================================
|
||
// ۹. تعویض عکس در صفحه محصول
|
||
// ==========================================
|
||
window.changeProductImage = function (btn, imgUrl) {
|
||
// تغییر عکس اصلی
|
||
const mainImg = document.getElementById('main-product-image');
|
||
if (mainImg) {
|
||
mainImg.src = imgUrl;
|
||
mainImg.setAttribute('data-large_image', imgUrl);
|
||
}
|
||
|
||
// تغییر کلاس فعال تامبنیلها
|
||
document.querySelectorAll('.gallery-thumb').forEach(function (thumb) {
|
||
thumb.classList.remove('active');
|
||
thumb.style.borderColor = '';
|
||
});
|
||
btn.classList.add('active');
|
||
};
|
||
|
||
// ==========================================
|
||
// ۱۰. ستارههای امتیازدهی سفارشی
|
||
// ==========================================
|
||
const starsContainer = document.getElementById('custom-star-rating');
|
||
const ratingInput = document.getElementById('rating');
|
||
if (starsContainer && ratingInput) {
|
||
const stars = starsContainer.querySelectorAll('.star');
|
||
|
||
stars.forEach(star => {
|
||
star.addEventListener('mouseenter', function() {
|
||
const val = this.dataset.value;
|
||
stars.forEach(s => {
|
||
s.style.color = s.dataset.value <= val ? '#D4A574' : '';
|
||
});
|
||
});
|
||
|
||
star.addEventListener('click', function() {
|
||
ratingInput.value = this.dataset.value;
|
||
stars.forEach(s => s.classList.remove('active'));
|
||
this.classList.add('active');
|
||
// رنگ دادن به همه ستارههای تا اون عدد
|
||
const val = this.dataset.value;
|
||
stars.forEach(s => {
|
||
if(s.dataset.value <= val) s.classList.add('active');
|
||
});
|
||
});
|
||
});
|
||
|
||
starsContainer.addEventListener('mouseleave', function() {
|
||
const currentVal = ratingInput.value;
|
||
stars.forEach(s => {
|
||
s.style.color = s.dataset.value <= currentVal ? '#D4A574' : '';
|
||
});
|
||
});
|
||
}
|
||
|
||
}); |