最近开发移动端h5,用的vant 移动端组件库框架,使用popup弹出层时,需要在底部固定一个操作模块。

但我发现在popup组件里使用fixed定位后,如果内容没有超出popup高度,底部fixed内容显示正常,否则内容超出出现滚动条后,底部fixed定位元素随页面滚动,fixed失效。效果如下:

正常情况和异常情况对比图(左正右异):

 

 解决办法有两种方式

方式一:

<div class="box-man">
		<van-popup
			class="menu-pop"
			v-model="showPopup"
			closeable
			close-on-popstate
			position="right"
			@close="close"
			@open="open"
			:lazy-render="false"
            //overflow: 'hidden' 为了隐藏内容超出
			:style="{ height: '100%', width: '100%', padding: '10% 6% 11%', overflow: 
            'hidden' }">

            //渲染的数据
			<div class="item" ref="itemBox">
				<div v-for="(item, index) in topicList" :key="index">
					<p v-text="item.title"></p>
				</div>
			</div>

            //底部fixed元素
			<div class="ft-btn" id="ft-btn">
				<span v-text="`clear`"></span>
				<van-button round block color="#391bf1" text="apply"></van-button>
			</div>
		</van-popup>
</div>



//所需样式
<style lang="stylus">
.box-man
    //为了隐藏滚动条
	.item
		width: 110%
		overflow: hidden
		overflow-y: auto

	.ft-btn
        width: 100%
        position: fixed;
		left: 0
		bottom: 0
		border-top: 1px solid #e7e7e7
        background-color: #fff;
</style>
//js代码

<script>
export default {
	name: 'PopularTopicsPopup',
	components: {},
	props: {
		showMenuPopup: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
            //控制popup的显示与隐藏
			showPopup: this.showMenuPopup,
            //模拟的数据
			topicList: Array(30).fill({
				title: 'Payments'
			})
		}
	},
	computed: {},
	watch: {
		showMenuPopup: {
			handler(newval, oldval) {
				this.showPopup = newval
			},
			immediate: true,
			deep: true
		}
	},
	created() {},
	mounted() {},
	// 销毁监听
	destroyed() {},
	methods: {
		//关闭弹出层时触发
		close() {
			this.showPopup = false
			this.$emit('showMenuPopups', this.showPopup)
		},
		//打开弹出层时触发
		open() {
			this.$nextTick(_ => {
				this.getHight()
			})
		},
		// 设置渲染数据内容区域的高度
		getHight() {
            //获取底部定位元素的高度和渲染数据盒子距离页面顶部距离
			let h = document.getElementById('ft-btn').clientHeight,
				itemOffTop = this.$refs.itemBox.offsetTop

            //设置渲染数据盒子的高度 限制它只能在指定高度内滚动内容
			this.$refs.itemBox.style.height =
				document.documentElement.clientHeight - h - itemOffTop + 'px'
			this.$forceUpdate()
		}
	}
}
</script>

 效果图:

 滑动到底部 能完全显示最后一项内容,并且底部fixed元素始终定位在底部。

方式二: 

//html代码

<div class="box-man">
		<van-popup
			class="menu-pop"
			v-model="showPopup"
			closeable
			close-on-popstate
			position="right"
			@close="close"
			@open="open"
			:lazy-render="false"
            //overflow: 'hidden' 移除内容超出隐藏样式,把padding最后一个值改为0
			:style="{ height: '100%', width: '100%', padding: '10% 6% 0' }">

            //渲染的数据
			<div class="item" ref="itemBox">
				<div v-for="(item, index) in topicList" :key="index">
					<p v-text="item.title"></p>
				</div>
			</div>
		</van-popup>

        //底部fixed元素
		<div class="ft-btn" id="ft-btn" v-if="showPopup">
			<span v-text="`clear`"></span>
			<van-button round block color="#391bf1" text="apply"></van-button>
		</div>
</div>



//所需样式
<style lang="stylus">
.box-man
    //去除item样式
	.item
/* 		width: 110%
		overflow: hidden
		overflow-y: auto */

	.ft-btn
        width: 100%
        position: fixed;
		left: 0
		bottom: 0
		border-top: 1px solid #e7e7e7
        background-color: #fff;
</style>
//js代码

<script>
export default {
	name: 'PopularTopicsPopup',
	components: {},
	props: {
		showMenuPopup: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
            //控制popup的显示与隐藏
			showPopup: this.showMenuPopup,
            //模拟的数据
			topicList: Array(30).fill({
				title: 'Payments'
			})
		}
	},
	computed: {},
	watch: {
		showMenuPopup: {
			handler(newval, oldval) {
				this.showPopup = newval
			},
			immediate: true,
			deep: true
		}
	},
	created() {},
	mounted() {},
	// 销毁监听
	destroyed() {},
	methods: {
		//关闭弹出层时触发
		close() {
			this.showPopup = false
			this.$emit('showMenuPopups', this.showPopup)
		},
		//打开弹出层时触发
		open() {
			this.$nextTick(_ => {
				this.getHight()
			})
		},
		// 设置渲染数据内容区域的padding-bottom
		getHight() {
            //获取底部定位元素的高度
			let h = document.getElementById('ft-btn').clientHeight

            //设置渲染数据盒子的内下边距 为了解决元素被fixed定位元素遮挡问题
			this.$refs.itemBox.style.paddingBottom = h + 'px'
			this.$forceUpdate()
		}
	}
}
</script>

 把需要定位的元素放在popup组件外,显示隐藏直接和控制弹出层的变量绑定同一个值,然后动态获取底部定位元素高度,赋值给渲染数据盒子的padding-bottom就可以了!

  效果图:

 滑动到底部 能完全显示最后一项内容,并且底部fixed元素始终定位在底部。 

 到此结束。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐