504 lines
17 KiB
JavaScript
504 lines
17 KiB
JavaScript
// Main JavaScript file for FIDEM Medical Center website
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Mobile menu functionality
|
||
initMobileMenu();
|
||
|
||
// Hero slider functionality
|
||
initHeroSlider();
|
||
|
||
// Smooth scrolling for navigation links
|
||
initSmoothScrolling();
|
||
|
||
// Initialize map
|
||
initMap();
|
||
|
||
// Navbar scroll effect
|
||
initNavbarScroll();
|
||
|
||
// Animation on scroll
|
||
initScrollAnimations();
|
||
|
||
// Service modal functionality
|
||
initServiceModal();
|
||
});
|
||
|
||
// Mobile Menu
|
||
function initMobileMenu() {
|
||
const mobileMenuToggle = document.getElementById('mobile-menu-toggle');
|
||
const navbarMenu = document.getElementById('navbar-menu');
|
||
const navLinks = document.querySelectorAll('.nav-link');
|
||
|
||
if (mobileMenuToggle && navbarMenu) {
|
||
mobileMenuToggle.addEventListener('click', function() {
|
||
navbarMenu.classList.toggle('active');
|
||
|
||
// Animate hamburger menu
|
||
const spans = mobileMenuToggle.querySelectorAll('span');
|
||
if (navbarMenu.classList.contains('active')) {
|
||
spans[0].style.transform = 'rotate(45deg) translateY(7px)';
|
||
spans[1].style.opacity = '0';
|
||
spans[2].style.transform = 'rotate(-45deg) translateY(-7px)';
|
||
} else {
|
||
spans[0].style.transform = 'none';
|
||
spans[1].style.opacity = '1';
|
||
spans[2].style.transform = 'none';
|
||
}
|
||
});
|
||
|
||
// Close mobile menu when clicking on nav links
|
||
navLinks.forEach(link => {
|
||
link.addEventListener('click', () => {
|
||
navbarMenu.classList.remove('active');
|
||
const spans = mobileMenuToggle.querySelectorAll('span');
|
||
spans[0].style.transform = 'none';
|
||
spans[1].style.opacity = '1';
|
||
spans[2].style.transform = 'none';
|
||
});
|
||
});
|
||
|
||
// Close mobile menu when clicking outside
|
||
document.addEventListener('click', function(e) {
|
||
if (!navbarMenu.contains(e.target) && !mobileMenuToggle.contains(e.target)) {
|
||
navbarMenu.classList.remove('active');
|
||
const spans = mobileMenuToggle.querySelectorAll('span');
|
||
spans[0].style.transform = 'none';
|
||
spans[1].style.opacity = '1';
|
||
spans[2].style.transform = 'none';
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// Hero Slider
|
||
function initHeroSlider() {
|
||
const slides = document.querySelectorAll('.hero-slide');
|
||
const navBtns = document.querySelectorAll('.hero-nav-btn');
|
||
const prevBtn = document.querySelector('.hero-arrow-prev');
|
||
const nextBtn = document.querySelector('.hero-arrow-next');
|
||
let currentSlide = 0;
|
||
let slideInterval;
|
||
|
||
if (slides.length === 0) return;
|
||
|
||
// Function to show specific slide
|
||
function showSlide(index) {
|
||
// Remove active class from all slides and nav buttons
|
||
slides.forEach(slide => slide.classList.remove('active'));
|
||
navBtns.forEach(btn => btn.classList.remove('active'));
|
||
|
||
// Add active class to current slide and nav button
|
||
slides[index].classList.add('active');
|
||
if (navBtns[index]) {
|
||
navBtns[index].classList.add('active');
|
||
}
|
||
|
||
currentSlide = index;
|
||
}
|
||
|
||
// Function to go to next slide
|
||
function nextSlide() {
|
||
const next = (currentSlide + 1) % slides.length;
|
||
showSlide(next);
|
||
}
|
||
|
||
// Function to go to previous slide
|
||
function prevSlide() {
|
||
const prev = (currentSlide - 1 + slides.length) % slides.length;
|
||
showSlide(prev);
|
||
}
|
||
|
||
// Auto-play functionality
|
||
function startAutoPlay() {
|
||
slideInterval = setInterval(nextSlide, 5000); // Change slide every 5 seconds
|
||
}
|
||
|
||
function stopAutoPlay() {
|
||
clearInterval(slideInterval);
|
||
}
|
||
|
||
// Event listeners for navigation buttons
|
||
navBtns.forEach((btn, index) => {
|
||
btn.addEventListener('click', () => {
|
||
showSlide(index);
|
||
stopAutoPlay();
|
||
startAutoPlay(); // Restart auto-play
|
||
});
|
||
});
|
||
|
||
// Event listeners for arrow buttons
|
||
if (nextBtn) {
|
||
nextBtn.addEventListener('click', () => {
|
||
nextSlide();
|
||
stopAutoPlay();
|
||
startAutoPlay();
|
||
});
|
||
}
|
||
|
||
if (prevBtn) {
|
||
prevBtn.addEventListener('click', () => {
|
||
prevSlide();
|
||
stopAutoPlay();
|
||
startAutoPlay();
|
||
});
|
||
}
|
||
|
||
// Pause auto-play on hover
|
||
const heroSection = document.querySelector('.hero');
|
||
if (heroSection) {
|
||
heroSection.addEventListener('mouseenter', stopAutoPlay);
|
||
heroSection.addEventListener('mouseleave', startAutoPlay);
|
||
}
|
||
|
||
// Start auto-play
|
||
startAutoPlay();
|
||
|
||
// Keyboard navigation
|
||
document.addEventListener('keydown', (e) => {
|
||
if (e.key === 'ArrowLeft') {
|
||
prevSlide();
|
||
stopAutoPlay();
|
||
startAutoPlay();
|
||
} else if (e.key === 'ArrowRight') {
|
||
nextSlide();
|
||
stopAutoPlay();
|
||
startAutoPlay();
|
||
}
|
||
});
|
||
}
|
||
|
||
// Smooth Scrolling
|
||
function initSmoothScrolling() {
|
||
const navLinks = document.querySelectorAll('a[href^="#"]');
|
||
|
||
navLinks.forEach(link => {
|
||
link.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
|
||
const targetId = this.getAttribute('href');
|
||
const targetSection = document.querySelector(targetId);
|
||
|
||
if (targetSection) {
|
||
const headerHeight = document.querySelector('.header').offsetHeight;
|
||
const targetPosition = targetSection.offsetTop - headerHeight - 20;
|
||
|
||
window.scrollTo({
|
||
top: targetPosition,
|
||
behavior: 'smooth'
|
||
});
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// Navbar Scroll Effect
|
||
function initNavbarScroll() {
|
||
const header = document.querySelector('.header');
|
||
let lastScrollY = window.scrollY;
|
||
|
||
window.addEventListener('scroll', () => {
|
||
const currentScrollY = window.scrollY;
|
||
|
||
if (currentScrollY > 100) {
|
||
header.style.background = 'rgba(255, 255, 255, 0.95)';
|
||
header.style.backdropFilter = 'blur(10px)';
|
||
} else {
|
||
header.style.background = '#ffffff';
|
||
header.style.backdropFilter = 'none';
|
||
}
|
||
|
||
// Hide/show header on scroll
|
||
if (currentScrollY > lastScrollY && currentScrollY > 200) {
|
||
header.style.transform = 'translateY(-100%)';
|
||
} else {
|
||
header.style.transform = 'translateY(0)';
|
||
}
|
||
|
||
lastScrollY = currentScrollY;
|
||
});
|
||
}
|
||
|
||
// Scroll Animations
|
||
function initScrollAnimations() {
|
||
const observerOptions = {
|
||
threshold: 0.1,
|
||
rootMargin: '0px 0px -50px 0px'
|
||
};
|
||
|
||
const observer = new IntersectionObserver((entries) => {
|
||
entries.forEach(entry => {
|
||
if (entry.isIntersecting) {
|
||
entry.target.classList.add('fade-in-up');
|
||
}
|
||
});
|
||
}, observerOptions);
|
||
|
||
// Observe elements that should animate on scroll
|
||
const animateElements = document.querySelectorAll('.service-card, .feature, .contact-item, .section-header');
|
||
animateElements.forEach(el => observer.observe(el));
|
||
}
|
||
|
||
// Initialize Yandex Map
|
||
function initMap() {
|
||
// Check if Yandex Maps API is loaded
|
||
if (typeof ymaps === 'undefined') {
|
||
console.log('Yandex Maps API not loaded');
|
||
// Create placeholder for map
|
||
createMapPlaceholder();
|
||
return;
|
||
}
|
||
|
||
ymaps.ready(function() {
|
||
// Точные координаты для г. Слоним, ул. Чапаева, 3
|
||
const coords = [53.092667, 25.321702];
|
||
|
||
const map = new ymaps.Map('map', {
|
||
center: coords,
|
||
zoom: 17,
|
||
controls: ['zoomControl', 'fullscreenControl']
|
||
});
|
||
|
||
// Add placemark for medical center
|
||
const placemark = new ymaps.Placemark(coords, {
|
||
balloonContentHeader: 'Медицинский центр ФИДЕМ',
|
||
balloonContentBody: 'г. Слоним, ул. Чапаева, 3',
|
||
balloonContentFooter: 'Режим работы: Ежедневно 8:00-20:00, без выходных',
|
||
hintContent: 'ФИДЕМ - Медицинский центр'
|
||
}, {
|
||
iconLayout: 'default#image',
|
||
iconImageHref: 'data:image/svg+xml;charset=utf-8,<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="12" fill="%2381C784"/><path d="M16 8c-2.2 0-4 1.8-4 4 0 3 4 8 4 8s4-5 4-8c0-2.2-1.8-4-4-4zm0 6c-1.1 0-2-0.9-2-2s0.9-2 2-2 2 0.9 2 2-0.9 2-2 2z" fill="white"/></svg>',
|
||
iconImageSize: [32, 32],
|
||
iconImageOffset: [-16, -32]
|
||
});
|
||
|
||
map.geoObjects.add(placemark);
|
||
|
||
// Open balloon on load
|
||
setTimeout(() => {
|
||
placemark.balloon.open();
|
||
}, 1000);
|
||
});
|
||
}
|
||
|
||
// Create map placeholder if Yandex Maps API is not available
|
||
function createMapPlaceholder() {
|
||
const mapContainer = document.getElementById('map');
|
||
if (mapContainer) {
|
||
mapContainer.innerHTML = `
|
||
<div style="display: flex; align-items: center; justify-content: center; height: 100%; background-color: #ecf0f1; color: #7f8c8d; flex-direction: column; text-align: center; padding: 2rem;">
|
||
<i class="fas fa-map-marker-alt" style="font-size: 3rem; color: #218F36; margin-bottom: 1rem;"></i>
|
||
<h3 style="margin-bottom: 0.5rem; color: #2c3e50;">Наш адрес</h3>
|
||
<p style="margin-bottom: 1rem;">г. Слоним, ул. Чапаева, 3</p>
|
||
<a href="https://yandex.ru/maps/?text=53.091667,25.315" target="_blank" style="color: #218F36; text-decoration: underline;">
|
||
Открыть в Яндекс.Картах
|
||
</a>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
// Utility function to throttle scroll events
|
||
function throttle(func, wait) {
|
||
let timeout;
|
||
return function executedFunction(...args) {
|
||
const later = () => {
|
||
clearTimeout(timeout);
|
||
func(...args);
|
||
};
|
||
clearTimeout(timeout);
|
||
timeout = setTimeout(later, wait);
|
||
};
|
||
}
|
||
|
||
// Active navigation link highlighting
|
||
function initActiveNavigation() {
|
||
const navLinks = document.querySelectorAll('.nav-link');
|
||
const sections = document.querySelectorAll('section[id]');
|
||
|
||
const highlightNavigation = throttle(() => {
|
||
const scrollY = window.pageYOffset;
|
||
const headerHeight = document.querySelector('.header').offsetHeight;
|
||
|
||
sections.forEach(section => {
|
||
const sectionHeight = section.offsetHeight;
|
||
const sectionTop = section.offsetTop - headerHeight - 50;
|
||
const sectionId = section.getAttribute('id');
|
||
|
||
if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
|
||
navLinks.forEach(link => {
|
||
link.classList.remove('active');
|
||
if (link.getAttribute('href') === `#${sectionId}`) {
|
||
link.classList.add('active');
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}, 100);
|
||
|
||
window.addEventListener('scroll', highlightNavigation);
|
||
}
|
||
|
||
// Initialize active navigation
|
||
document.addEventListener('DOMContentLoaded', initActiveNavigation);
|
||
|
||
// Phone number formatting for better UX
|
||
function formatPhoneNumbers() {
|
||
const phoneLinks = document.querySelectorAll('a[href^="tel:"]');
|
||
|
||
phoneLinks.forEach(link => {
|
||
link.addEventListener('click', function(e) {
|
||
// Analytics tracking could be added here
|
||
console.log('Phone number clicked:', this.href);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Initialize phone number formatting
|
||
document.addEventListener('DOMContentLoaded', formatPhoneNumbers);
|
||
|
||
// Form validation (if contact form is added later)
|
||
function initFormValidation() {
|
||
const forms = document.querySelectorAll('form');
|
||
|
||
forms.forEach(form => {
|
||
form.addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
|
||
// Basic form validation
|
||
const inputs = form.querySelectorAll('input[required], textarea[required]');
|
||
let isValid = true;
|
||
|
||
inputs.forEach(input => {
|
||
if (!input.value.trim()) {
|
||
isValid = false;
|
||
input.classList.add('error');
|
||
} else {
|
||
input.classList.remove('error');
|
||
}
|
||
});
|
||
|
||
if (isValid) {
|
||
// Form is valid, submit or process
|
||
console.log('Form submitted successfully');
|
||
// Add success message or redirect
|
||
} else {
|
||
console.log('Form validation failed');
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// Loading animation for images
|
||
function initImageLoading() {
|
||
const images = document.querySelectorAll('img');
|
||
|
||
images.forEach(img => {
|
||
if (!img.complete) {
|
||
img.classList.add('loading');
|
||
img.addEventListener('load', function() {
|
||
this.classList.remove('loading');
|
||
this.classList.add('loaded');
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
// Initialize image loading
|
||
document.addEventListener('DOMContentLoaded', initImageLoading);
|
||
|
||
// Accessibility improvements
|
||
function initAccessibility() {
|
||
// Skip to main content link
|
||
const skipLink = document.createElement('a');
|
||
skipLink.href = '#main';
|
||
skipLink.textContent = 'Перейти к основному содержанию';
|
||
skipLink.className = 'skip-link';
|
||
skipLink.style.cssText = `
|
||
position: absolute;
|
||
top: -40px;
|
||
left: 6px;
|
||
background: #218F36;
|
||
color: white;
|
||
padding: 8px;
|
||
text-decoration: none;
|
||
border-radius: 4px;
|
||
z-index: 1001;
|
||
transition: top 0.3s;
|
||
`;
|
||
|
||
skipLink.addEventListener('focus', function() {
|
||
this.style.top = '6px';
|
||
});
|
||
|
||
skipLink.addEventListener('blur', function() {
|
||
this.style.top = '-40px';
|
||
});
|
||
|
||
document.body.insertBefore(skipLink, document.body.firstChild);
|
||
|
||
// Add main id to main element
|
||
const main = document.querySelector('main');
|
||
if (main && !main.id) {
|
||
main.id = 'main';
|
||
}
|
||
}
|
||
|
||
// Initialize accessibility features
|
||
document.addEventListener('DOMContentLoaded', initAccessibility);
|
||
|
||
// Service Cards Expand/Collapse
|
||
// Service Modal
|
||
function initServiceModal() {
|
||
const serviceCards = document.querySelectorAll('.service-card');
|
||
const modal = document.getElementById('service-modal');
|
||
const modalOverlay = modal.querySelector('.modal-overlay');
|
||
const modalClose = modal.querySelector('.modal-close');
|
||
const modalIcon = modal.querySelector('.modal-icon i');
|
||
const modalTitle = modal.querySelector('.modal-title');
|
||
const modalDescription = modal.querySelector('.modal-description');
|
||
const modalProcedures = document.getElementById('modal-procedures');
|
||
|
||
// Открытие модального окна
|
||
serviceCards.forEach(card => {
|
||
card.addEventListener('click', function() {
|
||
const serviceKey = card.getAttribute('data-service');
|
||
const serviceData = servicesData[serviceKey];
|
||
|
||
if (serviceData) {
|
||
// Заполняем данные модального окна
|
||
modalIcon.className = serviceData.icon;
|
||
modalTitle.textContent = serviceData.title;
|
||
modalDescription.textContent = serviceData.description;
|
||
|
||
// Очищаем и заполняем список процедур
|
||
modalProcedures.innerHTML = '';
|
||
serviceData.procedures.forEach(procedure => {
|
||
const li = document.createElement('li');
|
||
li.textContent = procedure;
|
||
modalProcedures.appendChild(li);
|
||
});
|
||
|
||
// Показываем модальное окно
|
||
modal.classList.add('active');
|
||
document.body.style.overflow = 'hidden';
|
||
}
|
||
});
|
||
});
|
||
|
||
// Закрытие модального окна
|
||
function closeModal() {
|
||
modal.classList.remove('active');
|
||
document.body.style.overflow = '';
|
||
}
|
||
|
||
modalClose.addEventListener('click', closeModal);
|
||
modalOverlay.addEventListener('click', closeModal);
|
||
|
||
// Закрытие по Escape
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape' && modal.classList.contains('active')) {
|
||
closeModal();
|
||
}
|
||
});
|
||
}
|