38283-vm/assets/js/main.js
2026-02-08 08:34:40 +00:00

103 lines
3.4 KiB
JavaScript

// Cart Management
function addToCart(id, name, price, img) {
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
let found = cart.find(item => item.id === id);
if (found) {
found.qty++;
} else {
cart.push({ id, name, price, qty: 1, img });
}
localStorage.setItem('cart', JSON.stringify(cart));
updateCartBadge();
showToast(`${name} 已加入购物车`);
}
function updateCartBadge() {
let cart = JSON.parse(localStorage.getItem('cart') || '[]');
let count = cart.reduce((acc, item) => acc + item.qty, 0);
let badge = document.getElementById('cart-badge');
if (badge) {
if (count > 0) {
badge.textContent = count;
badge.classList.remove('d-none');
} else {
badge.classList.add('d-none');
}
}
}
// Toast Notification
function showToast(message) {
let toastContainer = document.getElementById('toast-container');
if (!toastContainer) {
toastContainer = document.createElement('div');
toastContainer.id = 'toast-container';
toastContainer.className = 'position-fixed bottom-0 end-0 p-3';
toastContainer.style.zIndex = '9999';
document.body.appendChild(toastContainer);
}
const toastId = 'toast-' + Date.now();
const toastHtml = `
<div id="${toastId}" class="toast align-items-center text-white bg-primary border-0 shadow-lg" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body fw-bold">
<i class="bi bi-check-circle-fill me-2"></i> ${message}
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
`;
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
const toastElement = document.getElementById(toastId);
const toast = new bootstrap.Toast(toastElement, { delay: 3000 });
toast.show();
toastElement.addEventListener('hidden.bs.toast', () => {
toastElement.remove();
});
}
// Initialize on load
document.addEventListener('DOMContentLoaded', function() {
updateCartBadge();
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
if (this.getAttribute('href') === '#') return;
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth'
});
}
});
});
// Add animation to cards on scroll
const observerOptions = {
threshold: 0.1
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
document.querySelectorAll('.glass-card').forEach(card => {
card.style.opacity = '0';
card.style.transform = 'translateY(20px)';
card.style.transition = 'all 0.6s cubic-bezier(0.23, 1, 0.32, 1)';
observer.observe(card);
});
});