ai-innovate-hub / script.js
zhengr's picture
生成一个AI 公司的网站
4e917b1 verified
// Counter animation for statistics
function animateCounters() {
const counters = document.querySelectorAll('.counter');
counters.forEach(counter => {
const target = parseInt(counter.getAttribute('data-target'));
const increment = target / 100;
let current = 0;
const updateCounter = () => {
current += increment;
if (current < target) {
counter.textContent = Math.ceil(current);
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target;
}
};
updateCounter();
});
}
// Intersection Observer for animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -100px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-fade-in');
// Trigger counter animation when stats section is visible
if (entry.target.querySelector('.counter')) {
animateCounters();
}
}
});
}, observerOptions);
// Observe all sections
document.addEventListener('DOMContentLoaded', () => {
const sections = document.querySelectorAll('section');
sections.forEach(section => observer.observe(section));
});
// Product filtering
function filterProducts(category) {
const products = document.querySelectorAll('#productsGrid .product-card');
const buttons = document.querySelectorAll('button[onclick^="filterProducts"]');
// Update active button
buttons.forEach(btn => {
btn.classList.remove('tab-active');
if (btn.getAttribute('onclick').includes(category)) {
btn.classList.add('tab-active');
}
});
// Filter products
products.forEach(product => {
if (category === 'all' || product.getAttribute('data-category') === category) {
product.style.display = 'block';
setTimeout(() => {
product.style.opacity = '1';
product.style.transform = 'scale(1)';
}, 10);
} else {
product.style.opacity = '0';
product.style.transform = 'scale(0.9)';
setTimeout(() => {
product.style.display = 'none';
}, 300);
}
});
}
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Parallax effect for hero section
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallax = document.querySelector('.hero-section');
if (parallax) {
parallax.style.transform = `translateY(${scrolled * 0.5}px)`;
}
});
// Mobile menu toggle (if needed)
function toggleMobileMenu() {
const menu = document.querySelector('.mobile-menu');
if (menu) {
menu.classList.toggle('active');
}
}
// Form validation
function validateForm(form) {
const inputs = form.querySelectorAll('input[required], textarea[required], select[required]');
let isValid = true;
inputs.forEach(input => {
if (!input.value.trim()) {
input.classList.add('border-red-500');
isValid = false;
} else {
input.classList.remove('border-red-500');
}
});
return isValid;
}
// Email validation
function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
// Phone number formatting
function formatPhoneNumber(input) {
const phoneNumber = input.value.replace(/\D/g, '');
const formattedNumber = phoneNumber.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
input.value = formattedNumber;
}
// Lazy loading for images
document.addEventListener('DOMContentLoaded', () => {
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
imageObserver.unobserve(img);
}
});
});
images.forEach(img => imageObserver.observe(img));
});
// Sticky header
window.addEventListener('scroll', () => {
const header = document.querySelector('header');
if (header) {
if (window.scrollY > 100) {
header.classList.add('shadow-lg');
} else {
header.classList.remove('shadow-lg');
}
}
});
// Copy to clipboard functionality
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
showNotification('Copied to clipboard!');
});
}
// Show notification
function showNotification(message, type = 'success') {
const notification = document.createElement('div');
notification.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 animate-fade-in ${
type === 'success' ? 'bg-green-500 text-white' : 'bg-red-500 text-white'
}`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.opacity = '0';
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
// Dark mode toggle
function toggleDarkMode() {
document.body.classList.toggle('dark-mode');
localStorage.setItem('darkMode', document.body.classList.contains('dark-mode'));
}
// Load dark mode preference
document.addEventListener('DOMContentLoaded', () => {
if (localStorage.getItem('darkMode') === 'true') {
document.body.classList.add('dark-mode');
}
});
// Initialize tooltips
document.addEventListener('DOMContentLoaded', () => {
const tooltips = document.querySelectorAll('[data-tooltip]');
tooltips.forEach(element => {
element.addEventListener('mouseenter', (e) => {
const tooltip = document.createElement('div');
tooltip.className = 'absolute bg-gray-800 text-white text-sm px-2 py-1 rounded z-50';
tooltip.textContent = e.target.getAttribute('data-tooltip');
tooltip.style.top = `${e.target.offsetTop - 30}px`;
tooltip.style.left = `${e.target.offsetLeft}px`;
tooltip.id = 'tooltip';
document.body.appendChild(tooltip);
});
element.addEventListener('mouseleave', () => {
const tooltip = document.getElementById('tooltip');
if (tooltip) {
document.body.removeChild(tooltip);
}
});
});
});
// Accordion functionality
function toggleAccordion(element) {
const content = element.nextElementSibling;
const icon = element.querySelector('.accordion-icon');
content.classList.toggle('hidden');
icon.classList.toggle('rotate-180');
}
// Tab functionality
function switchTab(tabId, contentId) {
// Hide all tab contents
const contents = document.querySelectorAll('[id^="tab-content-"]');
contents.forEach(content => content.classList.add('hidden'));
// Remove active class from all tabs
const tabs = document.querySelectorAll('[id^="tab-"]');
tabs.forEach(tab => tab.classList.remove('active'));
// Show selected content
document.getElementById(contentId).classList.remove('hidden');
// Add active class to selected tab
document.getElementById(tabId).classList.add('active');
}
// Search functionality
function searchItems(searchTerm, items) {
const filtered = items.filter(item =>
item.textContent.toLowerCase().includes(searchTerm.toLowerCase())
);
return filtered;
}
// Debounce function for search
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Performance monitoring
window.addEventListener('load', () => {
if ('performance' in window) {
const perfData = window.performance.timing;
const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
console.log(`Page load time: ${pageLoadTime}ms`);
}
});
// Error handling
window.addEventListener('error', (e) => {
console.error('JavaScript error:', e.error);
// You can send errors to a monitoring service here
});
// Service worker registration for PWA
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW registered: ', registration);
})
.catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}