Initial AI-generated site
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Navigation toggle
|
||||
const navToggle = document.querySelector('.nav-toggle');
|
||||
const navLinks = document.querySelector('.nav-links');
|
||||
|
||||
if (navToggle && navLinks) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
const isOpen = navToggle.getAttribute('aria-expanded') === 'true';
|
||||
navToggle.setAttribute('aria-expanded', !isOpen);
|
||||
navLinks.classList.toggle('open');
|
||||
document.body.style.overflow = isOpen ? '' : 'hidden';
|
||||
});
|
||||
|
||||
// Close menu when clicking a link
|
||||
navLinks.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
navToggle.setAttribute('aria-expanded', 'false');
|
||||
navLinks.classList.remove('open');
|
||||
document.body.style.overflow = '';
|
||||
});
|
||||
});
|
||||
|
||||
// Close on escape key
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && navLinks.classList.contains('open')) {
|
||||
navToggle.setAttribute('aria-expanded', 'false');
|
||||
navLinks.classList.remove('open');
|
||||
document.body.style.overflow = '';
|
||||
navToggle.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Reveal animations
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
if (!prefersReducedMotion) {
|
||||
const revealElements = document.querySelectorAll('.reveal');
|
||||
|
||||
const revealObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
});
|
||||
|
||||
revealElements.forEach(el => revealObserver.observe(el));
|
||||
} else {
|
||||
document.querySelectorAll('.reveal').forEach(el => {
|
||||
el.classList.add('visible');
|
||||
});
|
||||
}
|
||||
|
||||
// Stats counter animation
|
||||
const stats = document.querySelectorAll('.stat-number');
|
||||
|
||||
if (!prefersReducedMotion && stats.length) {
|
||||
const statsObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const target = parseInt(entry.target.getAttribute('data-target'), 10);
|
||||
animateCounter(entry.target, target);
|
||||
statsObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
|
||||
stats.forEach(stat => statsObserver.observe(stat));
|
||||
} else {
|
||||
stats.forEach(stat => {
|
||||
stat.textContent = stat.getAttribute('data-target');
|
||||
});
|
||||
}
|
||||
|
||||
function animateCounter(element, target) {
|
||||
let current = 0;
|
||||
const duration = 2000;
|
||||
const step = target / (duration / 16);
|
||||
|
||||
function update() {
|
||||
current += step;
|
||||
if (current < target) {
|
||||
element.textContent = Math.floor(current);
|
||||
requestAnimationFrame(update);
|
||||
} else {
|
||||
element.textContent = target;
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
// Set minimum date for booking form
|
||||
const dateInput = document.getElementById('booking-date');
|
||||
if (dateInput) {
|
||||
const today = new Date();
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
const minDate = tomorrow.toISOString().split('T')[0];
|
||||
dateInput.setAttribute('min', minDate);
|
||||
}
|
||||
|
||||
// Form handling
|
||||
const bookingForm = document.getElementById('bookingForm');
|
||||
const contactForm = document.getElementById('contactForm');
|
||||
|
||||
function showToast(message) {
|
||||
const toast = document.getElementById('toast');
|
||||
if (toast) {
|
||||
toast.textContent = message;
|
||||
toast.classList.add('show');
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
}, 4000);
|
||||
}
|
||||
}
|
||||
|
||||
function validatePhone(phone) {
|
||||
const cleaned = phone.replace(/[-\s]/g, '');
|
||||
return /^0[0-9]{9}$/.test(cleaned);
|
||||
}
|
||||
|
||||
if (bookingForm) {
|
||||
bookingForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const phone = bookingForm.querySelector('[name="phone"]').value;
|
||||
if (!validatePhone(phone)) {
|
||||
showToast('מספר הטלפון לא תקין. נא להזין מספר ישראלי.');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData(bookingForm);
|
||||
const data = Object.fromEntries(formData);
|
||||
|
||||
// Simulate form submission
|
||||
console.log('Booking request:', data);
|
||||
|
||||
showToast('הבקשה נשלחה בהצלחה! נחזור אליך תוך 24 שעות.');
|
||||
bookingForm.reset();
|
||||
});
|
||||
}
|
||||
|
||||
if (contactForm) {
|
||||
contactForm.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const phone = contactForm.querySelector('[name="phone"]').value;
|
||||
if (!validatePhone(phone)) {
|
||||
showToast('מספר הטלפון לא תקין. נא להזין מספר ישראלי.');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData(contactForm);
|
||||
const data = Object.fromEntries(formData);
|
||||
|
||||
// Simulate form submission
|
||||
console.log('Contact message:', data);
|
||||
|
||||
showToast('ההודעה נשלחה! נחזור אליך בהקדם.');
|
||||
contactForm.reset();
|
||||
});
|
||||
}
|
||||
|
||||
// Smooth scroll for anchor links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function(e) {
|
||||
const targetId = this.getAttribute('href');
|
||||
if (targetId === '#') return;
|
||||
|
||||
const target = document.querySelector(targetId);
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
const nav = document.querySelector('.main-nav');
|
||||
const navHeight = nav ? nav.offsetHeight : 0;
|
||||
const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - navHeight;
|
||||
|
||||
window.scrollTo({
|
||||
top: targetPosition,
|
||||
behavior: prefersReducedMotion ? 'auto' : 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Nav shadow on scroll
|
||||
const nav = document.querySelector('.main-nav');
|
||||
|
||||
if (nav) {
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.pageYOffset > 100) {
|
||||
nav.style.boxShadow = 'var(--shadow-sm)';
|
||||
} else {
|
||||
nav.style.boxShadow = 'none';
|
||||
}
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user