Skip to content

Commit e8c4034

Browse files
committed
minor
1 parent 4b44703 commit e8c4034

2 files changed

Lines changed: 83 additions & 74 deletions

File tree

assets/css/style.css

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -917,37 +917,41 @@ h1, h2, h3, p, li, .caption, .small {
917917
.next-btn{ right: 8px; }
918918
}
919919

920+
/* 基础设置 */
920921
.carousel-container {
921922
position: relative;
922923
max-width: 1000px;
923924
margin: 20px auto;
924-
overflow: hidden;
925-
user-select: none; /* 禁止选中文本 */
925+
overflow: hidden; /* 隐藏溢出 */
926+
user-select: none;
926927
-webkit-user-select: none;
927928
}
928929

929930
.carousel-window {
930931
width: 100%;
931932
position: relative;
932-
/* 蒙版让边缘融合 */
933+
/* 边缘虚化 */
933934
-webkit-mask-image: linear-gradient(to right, transparent 0%, black 5%, black 95%, transparent 100%);
934935
mask-image: linear-gradient(to right, transparent 0%, black 5%, black 95%, transparent 100%);
935936
}
936937

937938
.carousel-track {
938939
display: flex;
939-
gap: 15px;
940+
gap: 15px; /* 固定间距 15px */
940941
width: 100%;
941942
padding: 10px 0;
942943
cursor: grab;
943-
/* 启用硬件加速 */
944-
transform: translate3d(0, 0, 0);
944+
will-change: transform;
945945
}
946+
.carousel-track:active { cursor: grabbing; }
946947

948+
/* --- 卡片核心样式 --- */
947949
.carousel-card {
950+
/* 电脑端默认:60% */
948951
flex: 0 0 60%;
949-
max-width: 60%;
950-
transition: transform 0.4s ease-out, opacity 0.4s ease-out; /* 稍快一点 */
952+
width: 60%;
953+
954+
transition: transform 0.4s ease, opacity 0.4s ease;
951955
opacity: 0.3;
952956
transform: scale(0.9);
953957
display: flex;
@@ -957,35 +961,37 @@ h1, h2, h3, p, li, .caption, .small {
957961
z-index: 1;
958962
}
959963

960-
/* --- 手机端适配 --- */
964+
/* 手机端适配:75% (留出一点边给按钮) */
961965
@media (max-width: 768px) {
962966
.carousel-card {
963-
flex: 0 0 75%; /* 稍微改小一点点,留出缝隙给按钮 */
964-
max-width: 75%;
967+
flex: 0 0 75%;
968+
width: 75%;
965969
}
966970
}
967971

972+
/* 激活状态 */
968973
.carousel-card.is-active {
969974
opacity: 1;
970975
transform: scale(1);
971976
z-index: 10;
972977
}
973978

979+
/* 禁止动画类 (用于瞬移) */
974980
.no-transition, .no-transition * {
975981
transition: none !important;
976982
}
977983

984+
/* --- 视频区域 --- */
978985
.video-wrapper {
979986
width: 100%;
980987
aspect-ratio: 16 / 9;
981988
border-radius: 12px;
982989
overflow: hidden;
983990
background: #000;
984-
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
991+
box-shadow: 0 5px 20px rgba(0,0,0,0.3);
985992
transform: translateZ(0);
986993

987-
/* === 核心修复 === */
988-
/* 彻底禁止视频层接收点击,确保点击直接穿透到下层或不挡住上层 */
994+
/* 核心:彻底禁止视频层响应鼠标,让点击穿透到底下的图层 */
989995
pointer-events: none;
990996
}
991997

@@ -997,7 +1003,7 @@ h1, h2, h3, p, li, .caption, .small {
9971003
}
9981004

9991005
.caption {
1000-
margin-top: 10px;
1006+
margin-top: 12px;
10011007
font-size: 16px;
10021008
font-weight: bold;
10031009
color: #333;
@@ -1007,31 +1013,32 @@ h1, h2, h3, p, li, .caption, .small {
10071013
}
10081014
.carousel-card.is-active .caption { opacity: 1; }
10091015

1010-
/* === 箭头修复 === */
1016+
/* --- 按钮样式 (核弹级层级) --- */
10111017
.nav-btn {
10121018
position: absolute;
10131019
top: 50%;
10141020
transform: translateY(-50%);
1015-
width: 50px; /* 加大尺寸 */
1021+
width: 50px;
10161022
height: 50px;
10171023
border-radius: 50%;
10181024
background: rgba(255, 255, 255, 0.95);
1019-
box-shadow: 0 4px 12px rgba(0,0,0,0.4);
1025+
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
10201026
cursor: pointer;
1021-
1022-
/* === 核弹级层级 === */
1023-
z-index: 9999; /* 保证没有任何东西能盖住它 */
1024-
1027+
z-index: 9999; /* 保证最顶层 */
10251028
display: flex;
10261029
align-items: center;
10271030
justify-content: center;
10281031
color: #333;
10291032
border: none;
1030-
-webkit-tap-highlight-color: transparent; /* 去掉手机点击蓝框 */
1031-
1032-
/* 确保按钮自己可以被点 */
1033-
pointer-events: auto;
1033+
-webkit-tap-highlight-color: transparent;
1034+
pointer-events: auto; /* 恢复按钮的点击 */
10341035
}
10351036

10361037
.prev-btn { left: 10px; }
1037-
.next-btn { right: 10px; }
1038+
.next-btn { right: 10px; }
1039+
1040+
/* 手机上稍微把按钮往里收一点,防误触边缘 */
1041+
@media (max-width: 768px) {
1042+
.prev-btn { left: 5px; }
1043+
.next-btn { right: 5px; }
1044+
}

assets/js/main.js

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -743,18 +743,19 @@ function initDemoRotator(){
743743

744744
window.addEventListener('load', ()=>{ try{ initDemoRotator(); }catch(e){} });
745745
// 1. 初始化变量
746+
// 1. 获取元素
746747
const track = document.getElementById('track');
747748
const originalCards = document.querySelectorAll('.carousel-card');
748749
const prevBtn = document.getElementById('prevBtn');
749750
const nextBtn = document.getElementById('nextBtn');
750-
const gapPx = 15;
751+
const gapPx = 15; // 必须和 CSS 里的 gap 保持一致
751752

752-
// 动态计算宽度百分比
753+
// 2. 动态获取当前是从 60% 还是 75% 渲染
753754
function getCardWidthPercent() {
754755
return window.innerWidth < 768 ? 75 : 60;
755756
}
756757

757-
// 2. 克隆卡片
758+
// 3. 克隆首尾 (Clone)
758759
const firstClone = originalCards[0].cloneNode(true);
759760
const lastClone = originalCards[originalCards.length - 1].cloneNode(true);
760761
track.appendChild(firstClone);
@@ -764,11 +765,30 @@ let allCards = document.querySelectorAll('.carousel-card');
764765
let currentIndex = 1;
765766
let isTransitioning = false;
766767

767-
// 3. 核心切换函数
768+
// 4. 核心:更新位置 (使用纯 CSS calc,稳如老狗)
769+
function updateTrack(animate) {
770+
if (animate) {
771+
track.style.transition = 'transform 0.4s cubic-bezier(0.25, 1, 0.5, 1)';
772+
} else {
773+
track.style.transition = 'none';
774+
}
775+
776+
const wPercent = getCardWidthPercent();
777+
778+
// 公式解释:
779+
// 居中偏移量 = (100% - 卡片宽度%) / 2
780+
// 移动距离 = 居中偏移量 - (当前索引 * (卡片宽度% + 间距px))
781+
const centerOffset = (100 - wPercent) / 2;
782+
const val = `calc(${centerOffset}% - ${currentIndex} * (${wPercent}% + ${gapPx}px))`;
783+
784+
track.style.transform = `translateX(${val})`;
785+
}
786+
787+
// 5. 切换逻辑
768788
function switchSlide(direction) {
769789
if (isTransitioning) return;
770790

771-
// 边界保护
791+
// 防止快速点击越界
772792
if (direction === 1 && currentIndex >= allCards.length - 1) return;
773793
if (direction === -1 && currentIndex <= 0) return;
774794

@@ -778,52 +798,41 @@ function switchSlide(direction) {
778798
updateActive();
779799
}
780800

781-
// === 4. 事件绑定 (暴力修复点击问题) ===
801+
// 6. 事件绑定 (暴力绑定 click 和 touchend)
782802

783-
// 绑定点击
784-
nextBtn.addEventListener('click', (e) => {
785-
e.preventDefault();
786-
switchSlide(1);
787-
});
788-
prevBtn.addEventListener('click', (e) => {
789-
e.preventDefault();
790-
switchSlide(-1);
791-
});
803+
// 电脑端点击
804+
nextBtn.addEventListener('click', (e) => { e.preventDefault(); switchSlide(1); });
805+
prevBtn.addEventListener('click', (e) => { e.preventDefault(); switchSlide(-1); });
792806

793-
// 绑定触摸结束 (针对部分安卓机)
794-
// 为了防止 Click 和 Touchend 触发两次,我们加个简单的锁
807+
// 手机端触摸 (加锁防止双重触发)
795808
let touchLock = false;
796-
function handleTouchBtn(e, dir) {
797-
e.preventDefault(); // 防止触发后面的 click
798-
e.stopPropagation(); // 防止冒泡
809+
function handleTouch(e, dir) {
799810
if(touchLock) return;
800-
811+
e.preventDefault(); e.stopPropagation(); // 阻止冒泡
801812
switchSlide(dir);
802-
803813
touchLock = true;
804-
setTimeout(() => { touchLock = false; }, 300);
814+
setTimeout(() => touchLock = false, 300);
805815
}
816+
nextBtn.addEventListener('touchend', (e) => handleTouch(e, 1));
817+
prevBtn.addEventListener('touchend', (e) => handleTouch(e, -1));
806818

807-
nextBtn.addEventListener('touchend', (e) => handleTouchBtn(e, 1));
808-
prevBtn.addEventListener('touchend', (e) => handleTouchBtn(e, -1));
809-
810-
811-
// 5. 触摸滑动支持 (Swipe)
819+
// 7. 手机滑动支持 (Swipe)
812820
let touchStartX = 0;
813821
track.addEventListener('touchstart', e => { touchStartX = e.changedTouches[0].screenX; }, {passive: true});
814822
track.addEventListener('touchend', e => {
815823
const touchEndX = e.changedTouches[0].screenX;
816-
if (touchEndX < touchStartX - 50) switchSlide(1);
817-
if (touchEndX > touchStartX + 50) switchSlide(-1);
824+
if (touchEndX < touchStartX - 50) switchSlide(1); // 左滑 -> 下一张
825+
if (touchEndX > touchStartX + 50) switchSlide(-1); // 右滑 -> 上一张
818826
}, {passive: true});
819827

820-
821-
// 6. 无缝循环处理
828+
// 8. 无缝循环 & 视频同步
822829
track.addEventListener('transitionend', () => {
823830
isTransitioning = false;
824831
let targetIndex = -1;
825832

833+
// 到了克隆的最后一张 -> 跳回真实第1张
826834
if (currentIndex === allCards.length - 1) targetIndex = 1;
835+
// 到了克隆的第一张 -> 跳回真实最后一张
827836
else if (currentIndex === 0) targetIndex = allCards.length - 2;
828837

829838
if (targetIndex !== -1) {
@@ -837,7 +846,7 @@ track.addEventListener('transitionend', () => {
837846
allCards.forEach(c => c.classList.add('no-transition'));
838847

839848
currentIndex = targetIndex;
840-
updateTrack(false);
849+
updateTrack(false); // 重新定位
841850
updateActive();
842851

843852
void track.offsetHeight; // 强制重绘
@@ -848,26 +857,17 @@ track.addEventListener('transitionend', () => {
848857
}
849858
});
850859

851-
// 7. 更新视图逻辑
852-
function updateTrack(animate) {
853-
if (animate) track.style.transition = 'transform 0.4s ease-out';
854-
else track.style.transition = 'none';
855-
856-
const wPercent = getCardWidthPercent();
857-
const centerOffset = (100 - wPercent) / 2;
858-
const val = `calc(${centerOffset}% - ${currentIndex} * (${wPercent}% + ${gapPx}px))`;
859-
track.style.transform = `translateX(${val})`;
860-
}
861-
860+
// 9. 激活状态 (只播中间,两边暂停)
862861
function updateActive() {
863862
allCards.forEach((card, index) => {
864863
const v = card.querySelector('video');
865864
if (index === currentIndex) {
866865
card.classList.add('is-active');
867866
if (v) {
868-
v.muted = true;
869-
v.playsInline = true;
870-
v.play().catch(()=>{});
867+
v.muted = true;
868+
v.playsInline = true;
869+
// 必须加 catch 防止报错
870+
v.play().catch(()=>{});
871871
}
872872
} else {
873873
card.classList.remove('is-active');
@@ -879,4 +879,6 @@ function updateActive() {
879879
// 初始化
880880
updateTrack(false);
881881
updateActive();
882+
883+
// 监听窗口大小变化(自动适应横竖屏)
882884
window.addEventListener('resize', () => updateTrack(false));

0 commit comments

Comments
 (0)