fix: 首屏视频出现播放按钮

This commit is contained in:
liulujian 2026-06-05 14:34:51 +08:00
parent 8449757995
commit d43b4b17e2
2 changed files with 58 additions and 25 deletions

View File

@ -70,11 +70,10 @@ docker buildx build --platform linux/arm64 -t txw-all:1.0.0 -f devops/Dockerfile
代码变更后,重新构建并启动:
```bash
# 1. 重新构建镜像
bash build.sh 1.0.0-BETA
# 1. 加载新镜像
docker load -i txw-all-1.0.0-time.tar
# 2. 重启业务服务(使用新镜像)
docker-compose -f docker-compose.svc.yml up -d --build
docker-compose -f docker-compose.svc.yml up -d --force-recreate
```
### 查看镜像

View File

@ -6,18 +6,29 @@
<div class="container">
<!-- 顶部背景轮播 -->
<div class="top-box snap-section" id="section-hero" :style="{ minHeight: topBannerHeight + 'px' }">
<t-swiper class="top-banner-swiper" animation="fade" :height="topBannerHeight" :interval="10000" :duration="500"
:loop="true" :autoplay="true" theme="dark" :navigation="{ showSlideBtn: 'never' }">
<t-swiper
class="top-banner-swiper"
animation="fade"
:height="topBannerHeight"
:interval="10000"
:duration="500"
:loop="true"
:autoplay="true"
theme="dark"
:navigation="{ showSlideBtn: 'never' }"
:current="currentBannerIndex"
@change="onBannerChange"
>
<t-swiper-item v-for="(video, idx) in topBannerVideos" :key="idx">
<video
ref="bannerVideoRefs"
class="banner-video"
:src="video"
autoplay
muted
loop
playsinline
webkit-playsinline
preload="auto"
@loadeddata="onBannerVideoReady"
/>
</t-swiper-item>
</t-swiper>
@ -355,6 +366,7 @@ export default {
inputValue: '',
activeTab: 0,
topBannerHeight: 686,
currentBannerIndex: 0,
newsLoading: true,
scrollRoot: null,
sectionOffsets: [],
@ -530,6 +542,17 @@ export default {
if (window.visualViewport) {
window.visualViewport.addEventListener('resize', this.onViewportResize);
}
// Mac Safari
//
this._unlockBannerOnce = () => {
this.onUserInteractUnlockBanner();
['click', 'touchstart', 'keydown', 'scroll'].forEach((evt) => {
window.removeEventListener(evt, this._unlockBannerOnce);
});
};
['click', 'touchstart', 'keydown', 'scroll'].forEach((evt) => {
window.addEventListener(evt, this._unlockBannerOnce, { once: true, passive: true });
});
this.loadHotSearch();
this.fetchNewsData();
this.getTfwzxUrl();
@ -553,7 +576,7 @@ export default {
this._scrollRootResizeObserver.observe(this.scrollRoot);
}
}
this.ensureBannerVideosPlay();
this.playActiveBannerVideo();
this.jumpToSectionFromRoute(this.$route.query.section, false);
});
},
@ -564,6 +587,12 @@ export default {
window.visualViewport.removeEventListener('resize', this.onViewportResize);
}
}
if (this._unlockBannerOnce) {
['click', 'touchstart', 'keydown', 'scroll'].forEach((evt) => {
window.removeEventListener(evt, this._unlockBannerOnce);
});
this._unlockBannerOnce = null;
}
if (this._scrollRootResizeObserver) {
this._scrollRootResizeObserver.disconnect();
this._scrollRootResizeObserver = null;
@ -712,28 +741,33 @@ export default {
this.$nextTick(() => {
this.syncPortalFigmaStageLayout();
this.refreshSectionOffsets();
this.ensureBannerVideosPlay();
this.playActiveBannerVideo();
});
},
onBannerVideoReady(e) {
const video = e && e.target;
onBannerChange(index) {
this.currentBannerIndex = typeof index === 'number' ? index : 0;
this.$nextTick(() => this.playActiveBannerVideo());
},
playActiveBannerVideo() {
const list = this.$refs.bannerVideoRefs || [];
list.forEach((video, i) => {
if (!video) return;
if (i === this.currentBannerIndex) {
video.muted = true;
const playPromise = video.play();
if (playPromise && typeof playPromise.catch === 'function') {
playPromise.catch(() => {});
try { video.currentTime = 0; } catch (e) {}
const p = video.play();
if (p && typeof p.catch === 'function') {
p.catch((err) => console.warn('[banner video] play rejected:', err));
}
},
ensureBannerVideosPlay() {
if (!this.$el) return;
this.$el.querySelectorAll('.banner-video').forEach((video) => {
video.muted = true;
const playPromise = video.play();
if (playPromise && typeof playPromise.catch === 'function') {
playPromise.catch(() => {});
} else {
video.pause();
try { video.currentTime = 0; } catch (e) {}
}
});
},
onUserInteractUnlockBanner() {
this.playActiveBannerVideo();
},
refreshSectionOffsets() {
const scrollRoot = this.getScrollRoot();
if (!scrollRoot) return;