code optimized

This commit is contained in:
dadgam3er 2025-09-12 15:14:31 +00:00
parent 4df044c9c5
commit 1b0cdedc14
2 changed files with 171 additions and 280 deletions

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Global Tea Emporium - Premium Authentic Teas Worldwide</title> <title>Global Tea Emporium - Premium Authentic Teas Worldwide</title>
<link rel="stylesheet" href="styles.css" /> <link rel="stylesheet" href="styles.css" />
<script src="script.js"></script>
</head> </head>
<body> <body>
<!-- Skip to main content link for screen readers --> <!-- Skip to main content link for screen readers -->

448
script.js
View File

@ -1,295 +1,185 @@
// Global Tea Emporium - JavaScript Functionality // Global Tea Emporium - Optimized JavaScript
// Image Gallery Functionality document.addEventListener("DOMContentLoaded", function () {
document.addEventListener('DOMContentLoaded', function() { // ===== IMAGE GALLERY =====
console.log('Gallery script loading...'); const galleryImages = [
{
src: "images/green-tea-leaves.webp",
alt: "Premium Green Tea Leaves",
caption: "Premium Green Tea Leaves - Hand-picked from our finest gardens",
},
{
src: "images/Indian Black Teas.webp",
alt: "Indian Black Tea Selection",
caption:
"Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling",
},
{
src: "images/Oolong Selections.jpg",
alt: "Oolong Tea Collection",
caption:
"Traditional Oolong Selections - Complex flavors from Taiwan and China",
},
];
const galleryImages = [ const galleryImage = document.getElementById("gallery-image");
{ const galleryCaption = document.getElementById("gallery-caption");
src: 'images/green-tea-leaves.webp', const thumbnails = document.querySelectorAll(".thumbnail");
alt: 'Premium Green Tea Leaves', let currentIndex = 0;
caption: 'Premium Green Tea Leaves - Hand-picked from our finest gardens'
}, if (!galleryImage || !galleryCaption) return;
{
src: 'images/Indian Black Teas.webp', // Update gallery display
alt: 'Indian Black Tea Selection', function updateGallery(index) {
caption: 'Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling' currentIndex = index;
}, const image = galleryImages[index];
{ galleryImage.src = image.src;
src: 'images/Oolong Selections.jpg', galleryImage.alt = image.alt;
alt: 'Oolong Tea Collection', galleryCaption.textContent = image.caption;
caption: 'Traditional Oolong Selections - Complex flavors from Taiwan and China'
thumbnails.forEach((thumb, i) => {
thumb.classList.toggle("active", i === index);
});
}
// Navigation functions
const nextImage = () =>
updateGallery((currentIndex + 1) % galleryImages.length);
const prevImage = () =>
updateGallery(
(currentIndex - 1 + galleryImages.length) % galleryImages.length
);
// Event listeners
document.getElementById("next-btn")?.addEventListener("click", nextImage);
document.getElementById("prev-btn")?.addEventListener("click", prevImage);
thumbnails.forEach((thumb, index) => {
thumb.addEventListener("click", () => updateGallery(index));
});
// Auto-advance every 10 seconds
setInterval(nextImage, 10000);
// ===== CONTACT FORM =====
const contactForm = document.querySelector(".contact-form");
if (contactForm) {
const validateField = (field) => {
const group = field.closest(".form-group");
const error = group?.querySelector(".error-message");
let isValid = true;
let message = "";
group?.classList.remove("error", "success");
if (field.required && !field.value.trim()) {
isValid = false;
message = "This field is required.";
} else if (
field.type === "email" &&
field.value &&
!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(field.value)
) {
isValid = false;
message = "Please enter a valid email address.";
} else if (
field.type === "tel" &&
field.value &&
!/^[\d\s\-\+\(\)]+$/.test(field.value)
) {
isValid = false;
message = "Please enter a valid phone number.";
}
if (error) error.textContent = message;
group?.classList.add(
isValid && field.value.trim() ? "success" : isValid ? "" : "error"
);
return isValid;
};
contactForm.querySelectorAll("input, textarea").forEach((field) => {
field.addEventListener("blur", () => validateField(field));
field.addEventListener("input", () => {
if (field.closest(".form-group")?.classList.contains("error")) {
validateField(field);
} }
]; });
let currentImageIndex = 0;
const galleryImage = document.getElementById('gallery-image');
const galleryCaption = document.getElementById('gallery-caption');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const thumbnails = document.querySelectorAll('.thumbnail');
// Check if gallery elements exist
if (!galleryImage || !galleryCaption) {
console.log('Gallery image or caption not found');
return;
}
console.log('Gallery elements found:', {
image: !!galleryImage,
caption: !!galleryCaption,
prevBtn: !!prevBtn,
nextBtn: !!nextBtn,
thumbnails: thumbnails.length
}); });
function updateGallery(index) { contactForm.addEventListener("submit", (e) => {
console.log('Updating gallery to index:', index); e.preventDefault();
currentImageIndex = index; const fields = contactForm.querySelectorAll("input, textarea");
galleryImage.src = galleryImages[index].src; const isValid = Array.from(fields).every(validateField);
galleryImage.alt = galleryImages[index].alt;
galleryCaption.textContent = galleryImages[index].caption;
// Update active thumbnail if (isValid) {
thumbnails.forEach((thumb, i) => { const submitBtn = contactForm.querySelector(".submit-btn");
thumb.classList.toggle('active', i === index); const originalText = submitBtn.textContent;
}); submitBtn.textContent = "Sending...";
} submitBtn.disabled = true;
function nextImage() { setTimeout(() => {
console.log('Next image clicked'); const formData = new FormData(contactForm);
const newIndex = (currentImageIndex + 1) % galleryImages.length; const data = Object.fromEntries(formData);
updateGallery(newIndex); alert(`Thank you, ${data.name}! We'll contact you at ${data.email}.`);
} contactForm.reset();
fields.forEach((f) =>
function prevImage() { f.closest(".form-group")?.classList.remove("error", "success")
console.log('Previous image clicked'); );
const newIndex = (currentImageIndex - 1 + galleryImages.length) % galleryImages.length; submitBtn.textContent = originalText;
updateGallery(newIndex); submitBtn.disabled = false;
} }, 2000);
}
// Event listeners for gallery controls
if (prevBtn) {
console.log('Adding prev button listener');
prevBtn.addEventListener('click', prevImage);
} else {
console.log('Prev button not found');
}
if (nextBtn) {
console.log('Adding next button listener');
nextBtn.addEventListener('click', nextImage);
} else {
console.log('Next button not found');
}
// Thumbnail click events
thumbnails.forEach((thumbnail) => {
thumbnail.addEventListener('click', () => {
const index = parseInt(thumbnail.getAttribute('data-index'));
console.log('Thumbnail clicked, index:', index);
if (!isNaN(index)) {
updateGallery(index);
}
});
}); });
}
// Auto-advance gallery every 5 seconds // ===== FAQ ACCORDION =====
setInterval(nextImage, 5000); document.querySelectorAll(".faq-question").forEach((question) => {
console.log('Gallery initialized successfully'); question.addEventListener("click", function () {
}); // End of DOMContentLoaded for gallery const answer = this.nextElementSibling;
const toggle = this.querySelector(".faq-toggle");
const isOpen = this.getAttribute("aria-expanded") === "true";
// Enhanced Contact Form Validation // Close all other FAQs
document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll(".faq-question").forEach((q) => {
const contactForm = document.querySelector('.contact-form'); if (q !== this) {
q.setAttribute("aria-expanded", "false");
if (contactForm) { q.nextElementSibling?.classList.remove("active");
const formGroups = contactForm.querySelectorAll('.form-group'); q.querySelector(".faq-toggle")?.classList.remove("active");
// Real-time validation function
function validateField(field) {
const formGroup = field.closest('.form-group');
const errorSpan = formGroup.querySelector('.error-message');
let isValid = true;
let errorMessage = '';
// Remove previous validation classes
formGroup.classList.remove('error', 'success');
// Validate required fields
if (field.hasAttribute('required') && !field.value.trim()) {
isValid = false;
errorMessage = 'This field is required.';
} else if (field.type === 'email' && field.value) {
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(field.value)) {
isValid = false;
errorMessage = 'Please enter a valid email address.';
}
} else if (field.type === 'tel' && field.value) {
// Phone validation (basic)
const phoneRegex = /^[\d\s\-\+\(\)]+$/;
if (!phoneRegex.test(field.value)) {
isValid = false;
errorMessage = 'Please enter a valid phone number.';
}
} else if (field.tagName === 'TEXTAREA' && field.value.length < 10 && field.hasAttribute('required')) {
// Message length validation
isValid = false;
errorMessage = 'Message must be at least 10 characters long.';
}
// Display validation results
if (errorSpan) {
errorSpan.textContent = errorMessage;
}
if (isValid && field.value.trim()) {
formGroup.classList.add('success');
} else if (!isValid) {
formGroup.classList.add('error');
}
return isValid;
} }
});
// Add real-time validation to all form fields // Toggle current FAQ
formGroups.forEach(group => { this.setAttribute("aria-expanded", !isOpen);
const input = group.querySelector('input, textarea'); answer?.classList.toggle("active");
if (input) { toggle?.classList.toggle("active");
input.addEventListener('blur', () => validateField(input)); });
input.addEventListener('input', () => { });
if (group.classList.contains('error')) {
validateField(input);
}
});
}
});
contactForm.addEventListener('submit', function(e) { // ===== HOVER EFFECTS =====
e.preventDefault(); document
.querySelectorAll(".services-list li, .value-item, .timeline-item")
.forEach((item) => {
item.addEventListener("mouseenter", () => {
item.style.transform = "translateY(-2px)";
item.style.transition = "transform 0.3s ease";
});
item.addEventListener("mouseleave", () => {
item.style.transform = "translateY(0)";
});
});
let isFormValid = true; // ===== ACTIVE NAVIGATION =====
const formData = new FormData(contactForm); const currentPage = location.pathname.split("/").pop();
const data = Object.fromEntries(formData); document.querySelectorAll(".main-nav a").forEach((link) => {
const linkPage = link.getAttribute("href");
// Validate all fields if (
formGroups.forEach(group => { linkPage === currentPage ||
const input = group.querySelector('input, textarea'); (currentPage === "" && linkPage === "index.html")
if (input && !validateField(input)) { ) {
isFormValid = false; link.style.backgroundColor = "#daa520";
} link.style.color = "#5d4037";
});
if (!isFormValid) {
// Focus on first error field
const firstError = contactForm.querySelector('.form-group.error input, .form-group.error textarea');
if (firstError) {
firstError.focus();
}
return;
}
// Simulate form submission with loading state
const submitBtn = contactForm.querySelector('.submit-btn');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Sending...';
submitBtn.disabled = true;
setTimeout(() => {
alert(`Thank you for your message, ${data.name}! We'll get back to you soon at ${data.email}.`);
contactForm.reset();
formGroups.forEach(group => group.classList.remove('error', 'success'));
submitBtn.textContent = originalText;
submitBtn.disabled = false;
}, 2000);
});
} }
}); });
// FAQ Accordion Functionality
document.addEventListener('DOMContentLoaded', function() {
const faqQuestions = document.querySelectorAll('.faq-question');
faqQuestions.forEach(question => {
question.addEventListener('click', function() {
const answer = this.nextElementSibling;
const toggle = this.querySelector('.faq-toggle');
const isExpanded = this.getAttribute('aria-expanded') === 'true';
// Close all other FAQ items
faqQuestions.forEach(otherQuestion => {
if (otherQuestion !== this) {
const otherAnswer = otherQuestion.nextElementSibling;
const otherToggle = otherQuestion.querySelector('.faq-toggle');
otherQuestion.setAttribute('aria-expanded', 'false');
otherAnswer.classList.remove('active');
otherToggle.classList.remove('active');
}
});
// Toggle current FAQ item
this.setAttribute('aria-expanded', !isExpanded);
answer.classList.toggle('active');
toggle.classList.toggle('active');
});
// Add keyboard navigation
question.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.click();
}
});
});
});
// Smooth scrolling for navigation links
document.addEventListener('DOMContentLoaded', function() {
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
// Check if it's an internal link
if (this.hostname === window.location.hostname) {
// Add a subtle animation effect
this.style.transform = 'scale(0.95)';
setTimeout(() => {
this.style.transform = 'scale(1)';
}, 150);
}
});
});
});
// Add hover effects to service items
document.addEventListener('DOMContentLoaded', function() {
const serviceItems = document.querySelectorAll('.services-list li, .value-item, .timeline-item');
serviceItems.forEach(item => {
item.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.transition = 'transform 0.3s ease';
});
item.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
});
// Active navigation highlighting
document.addEventListener('DOMContentLoaded', function() {
const currentPage = window.location.pathname.split('/').pop();
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(link => {
const linkPage = link.getAttribute('href');
if (linkPage === currentPage || (currentPage === '' && linkPage === 'index.html')) {
link.style.backgroundColor = '#daa520';
link.style.color = '#5d4037';
}
});
}); });