|
@@ -0,0 +1,139 @@
|
|
|
+// 页面加载完成后执行
|
|
|
+document.addEventListener('DOMContentLoaded', function() {
|
|
|
+ // 添加卡片点击效果
|
|
|
+ addCardClickEffects();
|
|
|
+
|
|
|
+ // 添加滚动动画
|
|
|
+ addScrollAnimations();
|
|
|
+
|
|
|
+ // 添加触摸反馈
|
|
|
+ addTouchFeedback();
|
|
|
+});
|
|
|
+
|
|
|
+// 添加卡片点击效果
|
|
|
+function addCardClickEffects() {
|
|
|
+ const cards = document.querySelectorAll('.card');
|
|
|
+
|
|
|
+ cards.forEach((card, index) => {
|
|
|
+ // 鼠标悬停效果
|
|
|
+ card.addEventListener('mouseenter', function() {
|
|
|
+ this.style.transform = 'translateY(-4px) scale(1.02)';
|
|
|
+ });
|
|
|
+
|
|
|
+ card.addEventListener('mouseleave', function() {
|
|
|
+ this.style.transform = 'translateY(0) scale(1)';
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 添加滚动动画
|
|
|
+function addScrollAnimations() {
|
|
|
+ const cards = document.querySelectorAll('.card');
|
|
|
+
|
|
|
+ const observer = new IntersectionObserver((entries) => {
|
|
|
+ entries.forEach((entry, index) => {
|
|
|
+ if (entry.isIntersecting) {
|
|
|
+ entry.target.style.opacity = '0';
|
|
|
+ entry.target.style.transform = 'translateY(30px)';
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ entry.target.style.transition = 'all 0.6s ease';
|
|
|
+ entry.target.style.opacity = '1';
|
|
|
+ entry.target.style.transform = 'translateY(0)';
|
|
|
+ }, index * 100);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, {
|
|
|
+ threshold: 0.1,
|
|
|
+ rootMargin: '0px 0px -50px 0px'
|
|
|
+ });
|
|
|
+
|
|
|
+ cards.forEach(card => {
|
|
|
+ observer.observe(card);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+// 添加触摸反馈
|
|
|
+function addTouchFeedback() {
|
|
|
+ const cards = document.querySelectorAll('.card');
|
|
|
+
|
|
|
+ cards.forEach(card => {
|
|
|
+ card.addEventListener('touchstart', function() {
|
|
|
+ this.style.transform = 'scale(0.98)';
|
|
|
+ });
|
|
|
+
|
|
|
+ card.addEventListener('touchend', function() {
|
|
|
+ this.style.transform = 'scale(1)';
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+// 添加CSS动画样式
|
|
|
+const style = document.createElement('style');
|
|
|
+style.textContent = `
|
|
|
+ @keyframes ripple {
|
|
|
+ to {
|
|
|
+ transform: scale(4);
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .card {
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ .card:active {
|
|
|
+ transform: scale(0.98) !important;
|
|
|
+ }
|
|
|
+`;
|
|
|
+
|
|
|
+document.head.appendChild(style);
|
|
|
+
|
|
|
+// 添加页面加载动画
|
|
|
+window.addEventListener('load', function() {
|
|
|
+ document.body.style.opacity = '0';
|
|
|
+ document.body.style.transition = 'opacity 0.5s ease';
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ document.body.style.opacity = '1';
|
|
|
+ }, 100);
|
|
|
+});
|
|
|
+
|
|
|
+// 添加键盘导航支持
|
|
|
+document.addEventListener('keydown', function(e) {
|
|
|
+ const cards = document.querySelectorAll('.card');
|
|
|
+ const currentIndex = Array.from(cards).findIndex(card =>
|
|
|
+ card === document.activeElement || card.contains(document.activeElement)
|
|
|
+ );
|
|
|
+
|
|
|
+ let nextIndex = currentIndex;
|
|
|
+
|
|
|
+ switch(e.key) {
|
|
|
+ case 'ArrowDown':
|
|
|
+ e.preventDefault();
|
|
|
+ nextIndex = Math.min(currentIndex + 1, cards.length - 1);
|
|
|
+ break;
|
|
|
+ case 'ArrowUp':
|
|
|
+ e.preventDefault();
|
|
|
+ nextIndex = Math.max(currentIndex - 1, 0);
|
|
|
+ break;
|
|
|
+ case 'Enter':
|
|
|
+ case ' ':
|
|
|
+ e.preventDefault();
|
|
|
+ if (currentIndex >= 0) {
|
|
|
+ cards[currentIndex].click();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nextIndex !== currentIndex && nextIndex >= 0) {
|
|
|
+ cards[nextIndex].focus();
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 为卡片添加焦点样式
|
|
|
+document.querySelectorAll('.card').forEach(card => {
|
|
|
+ card.setAttribute('tabindex', '0');
|
|
|
+});
|