在移动端的项目中,需要实现有效阅读标记的需求,此功能在实现iframe 嵌入PDF预览时,需要在下滑到底部时显示标记按钮,但是在iOS中,因为滚动穿透的问题,在PDF区域触底后无法触发外层的滚动事件,后经过查询得知,这是因为 iOS 的滚动机制和 iframe 的滚动容器特性导致的。下面是几种解决该问题的方法:
方法一:使用 webkit-overflow-scrolling 属性
在 iframe 中添加 webkit-overflow-scrolling: touch 属性可以增强滚动的流畅性,同时也可能解决滚动穿透问题。
.pdf-viewer {
width: 100%;
height: calc(100vh - 76rpx);
-webkit-overflow-scrolling: touch; /* 兼容 iOS 滚动效果 */
overflow-scrolling: touch;
z-index: 1;
}
方法二:监听 iframe 的滚动事件
通过监听 iframe 的滚动事件,当 iframe 滚动到底部时,手动触发外层容器的滚动。
export default {
data() {
return {
//资讯对象
article: {
summary: ""
},
buttonStatus: 0, // 0 未标记;1 已标记;
courseId: "",
//头部背景
pdfViewer: null
}
},
onLoad(option) {
watermark.load({ watermark_txt: this.vuex_user.showName, watermark_fontsize: '12px', watermark_alpha: 0.15, watermark_angle: 25 })
this.loadData(option.id);
this.courseId = option.id;
this.countdownInterval()
//获取微信分享
// #ifdef H5
if (this.isWechat) {
this.$u.wx.wxShare()
}
// #endif
},
beforeDestroy() {
watermark.load({ watermark_txt: ' ' })
if (this.iframeRef) {
this.iframeRef.contentWindow.removeEventListener('scroll', this.handleIframeScroll)
}
},
methods: {
loadData(id) {
//资讯详情
this.$u.api.articleInfo(id).then(res => {
this.article = res
this.buttonStatus = this.article.fullReadFlag
});
},
lineSignUp() {
this.$u.api.articleDone(this.courseId).then(res => {
this.buttonStatus = 1 // 已标记
});
},
// 定义一个定时器,每秒执行一次
countdownInterval() {
const t = setInterval(() => {
// 秒数减 1
if (this.article.validReadingTime > 0) {
this.article.validReadingTime--
}
// 当倒计时到 0 时,清除定时器
if (this.article.validReadingTime == 0) {
clearInterval(t)
}
}, 1000)
},
onPdfLoad() {
const pdfFrame = this.$refs.pdfViewer;
const scrollContainer = pdfFrame.contentDocument.body
const viewerContainer = scrollContainer.querySelector('#viewerContainer');
viewerContainer.addEventListener('scroll', ()=> {
const isAtBottom = viewerContainer.scrollTop + viewerContainer.clientHeight >= viewerContainer.scrollHeight - 100;
if (isAtBottom) {
this.handleMessage()
}
});
},
handleMessage() {
// window.scrollBy(0, 10); // 可调整滚动距离
const effective = document.getElementsByClassName('u-effective')
console.log('effective', effective)
effective[0].style.position = 'fixed'
effective[0].style.left = '0'
effective[0].style.bottom = '0'
}
}
}
方法三:调整 iframe 的高度
可以动态调整 iframe 的高度,使其不会填满整个视口,这样当 iframe 滚动到底部时,就可以触发外层容器的滚动。
export default {
data() {
return {
//资讯对象
article: {
summary: ""
},
buttonStatus: 0, // 0 未标记;1 已标记;
courseId: "",
//头部背景
iframeHeight: 'calc(100vh - 150rpx)' // 调整高度
}
},
// ... 其他代码保持不变
methods: {
loadData(id) {
//资讯详情
this.$u.api.articleInfo(id).then(res => {
this.article = res
this.buttonStatus = this.article.fullReadFlag
});
},
// ... 其他代码保持不变
}
}
.pdf-viewer {
width: 100%;
height: var(--iframe-height); /* 使用动态高度 */
-webkit-overflow-scrolling: touch; /* 兼容 iOS 滚动效果 */
overflow-scrolling: touch;
z-index: 1;
}
作者是通过第二种方法解决的,遇到此问题的博友可根据实际情况,尝试解决。