Vue的項(xiàng)目类垦, 彈窗的文檔是用iframe引入html顯示的拗秘,但新增了文檔必須拉到最底部才能操作按鈕颂跨,iframe無(wú)法監(jiān)聽到scroll事件
需求
實(shí)現(xiàn)如下:
<template lang="pug">
.main-wrap
el-dialog(
v-if="isShow" // 每次展示都重新渲染以便滾動(dòng)條復(fù)原
title="Document"
width="700px" // 固定寬度以便確認(rèn)scrollTop
:visible.sync="isShow")
p.content#content(v-html="text" @scroll="scroll") // 文檔展示
.footer(slot="footer" v-if="isCheck")
el-button(@click="isShow = false") {{$t('common.cancel')}}
el-button(
:disabled="disabled"
type="primary"
@click="confirm") {{$t('common.loan')}}
</template>
<script>
export default {
data () {
return {
isShow: false, //是否顯示彈窗
text: '', // 文檔內(nèi)容
disabled: true // 按鈕是否可以操作
}
},
methods: {
// 每次顯示彈窗的時(shí)候按鈕不能操作復(fù)位
toShow (row) {
this.disabled = true
},
// 獲取文檔內(nèi)容并解析
async getHtml () {
// 判斷環(huán)境
const location = window.location
let url = ''
let hostname = location.hostname
if (hostname === 'localhost') {
url = `${location.origin}/static/doct.html`
} else {
url = `${location.origin}/dist/static/dot.html`
}
let headers = new Headers()
// 設(shè)置fetch請(qǐng)求頭
headers.append('Content-Type', 'text/plain')
fetch(url, {
headers
}).then((res) => {
return res.text()
}).then(res => {
this.text = res
})
},
// 判斷文檔滾動(dòng)位置
scroll (v) {
if (!this.disabled) return false // 如果到底部就再設(shè)置了
let top = v.target.scrollTop
this.disabled = (v.target.scrollHeight - top !== v.target.clientHeight) // 到底部到話就可操作
}
},
async mounted () {
await this.getHtml()
}
}
</script>
<style scoped>
// 文檔內(nèi)容樣式
.content {
border: 3px solid #ccc;
padding: 15px;
height: 400px;
overflow-y: scroll;
}
</style>
原理:
- 通過fetch獲取遠(yuǎn)程html并解析為text;
- 通過v-html把解析過后的字符串渲染到模板中辛萍;
3.監(jiān)聽文檔的scroll事件并判斷文檔的scrollTop是否已經(jīng)到底部,同步到按鈕的disabled
- element.scrollTop可以獲取或設(shè)置一個(gè)元素的內(nèi)容垂直滾動(dòng)像素?cái)?shù), scrollHeight
- Element.scrollHeight 這個(gè)只讀屬性是一個(gè)元素內(nèi)容高度的度量羡藐,包括由于溢出導(dǎo)致的視圖中不可見內(nèi)容贩毕。
判斷元素是否到底部
element.scrollHeight - element.scrollTop === element.clientHeight