先上代码:
<template>
<div>
Metpoid created this component.
<div class="red" :style="{ height: testHeight }">box One</div>
<div class="blue" :style="{ width: testWidth }">box Two</div>
</div>
</template>
<script>
// 这个组件是为了测试页面元素随着视口的宽高变化而变化
export default {
name: 'testViewsHOrW',
data () {
return {
testHeight: '',
testWidth: ''
}
},
// 在created 中对变量赋值 , 当然你也可以在data里面就对变量直接赋值
created () {
this.testHeight = window.innerHeight - 200 + 'px'
this.testWidth = window.innerWidth - 50 + 'px'
},
mounted () {
const that = this
window.onresize = that.throttle(function () {
that.testHeight = window.innerHeight - 200 + 'px'
that.testWidth = window.innerWidth - 50 + 'px'
}, 1000)
},
methods: {
// 这是节流函数
// fn为你想要被节流的函数 , delay为延时的时间
throttle (fn, delay = 1500) {
let inThrottle, lastFn, lastTime
return function () {
const context = this
const args = arguments
if (!inThrottle) {
fn.apply(context, args)
lastTime = Date.now()
inThrottle = true
} else {
clearTimeout(lastFn)
lastFn = setTimeout(function () {
if (Date.now() - lastTime >= delay) {
fn.apply(context, args)
lastTime = Date.now()
}
}, Math.max(delay - (Date.now() - lastTime), 0))
}
}
}
}
}
</script>
<style lang="less" scoped>
.red {
background-color: red;
color: #fff;
}
.blue {
background-color: blue;
color: #fff;
}
</style>
完整的效果代码我放在上面了,如果你想直接体验一下,可以直接复制去运行
代码浅析
1.要想达到让页面元素随着视口的宽高变化而变化,首先要做的就是能够获取到视口的宽高。
本文中使用的是 window.innerHeight ; window.innerWidth
当然你也可以使用 document.body.clientHeight ; document.documentElement.clientHeight 等等,根据实际情况做出判断,
前端尺寸的获取可以参考:
三大尺寸家族
1.offset家族 : 获取 “元素自身” 的真实宽高与位置
offsetWidth/offsetHeight : 获取自身真实宽高 = width + padding*2 + border*2
offsetLeft/top : 元素自身 左/上 外边框 到 定位父级 左/下 内边框距离
2.scroll家族 : 获取 “元素内容” 的真实宽高与位置
scrollWidth/scrollHeight : 获取元素‘内容’的宽高
scrollLeft/scrollTop : 元素内容 左/上 滚动出去的距离
3.client家族 : 获取元素‘可视区域’的宽高与位置
clientWidth/clientHeight : 获取元素‘可视区域’的宽高
clientLeft/clientTop : 获取元素‘可视区域’的位置(左边框与右边框)
三大家族特点
(1)获取的是number类型
(2)只能获取,不能设置
或者查看这篇文章# 前端页面中的各种宽高和位置
2.触发事件,使元素的宽高被重新赋值
本文尝试的方法为,在 mounted 中让 window 注册 resize 方法,在这个方法中让元素的宽高被重新赋值,这里要注意的点是,this 的指向。
lil tips:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。\
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,\
这样this的指向才是vm 或 组件实例对象。
3.为window注册事件,这些事件的触发频率都是非常高的,所以要减少频率。
要达到这个效果可以使用函数节流,封装好的节流函数我已经放在上文的代码中了,当然你也可以尝试自己封装一个。