前言
你的 点赞、收藏、关注 ,是我继续写下去的唯一动力 ~
先看效果:
众所周知,我们平时获取获取窗口的宽高都是 JavaScript
获取的,要不然直接通过 JavaScript
的 resize
监听页面宽高变化。
但现在不一样了!我们可以直接通过 CSS
获取 window
的尺寸,并且可以通过变量来进行使用。
在我第一眼看到这个消息的感觉是不可置信!但这是真的,下面我将带大家复习一下在 Vue、React、Svelte 以及原生 JavaScript
中如何获取 window
尺寸,然后带大家一览新的获取方案!
示例
点击马上掘金中间的左右箭头,可以查看高度的监听。
正文
本来是先写的传统方案获取尺寸,但想到大家可能都了解怎么实现,就放在了后面,大家有需要可以自己在后面复习一下。😊😊
CSS 获取窗口大小
属性定义
通过 CSS 新增的 @property
,可以让我们创建自定义属性,并给它定义其类型以及初始值(初始值在不经改变的情况下一直是该值)。
利用这个功能,我们可以创建一个宽高属性出来。
@property --w_raw {
syntax: '<length>';
inherits: true;
initial-value: 100vw;
}
@property --h_raw {
syntax: '<length>';
inherits: true;
initial-value: 100vh;
}
这其中:
syntax
是这个属性的单位,我们给它设置为<length>
,以便于让浏览器理解这是一个长度单位initial-value
是这个属性的初始值,如果不修改,它一直是100vw
inherits
是这个属性是否可以被继承,设置false | true
都不影响使用
计算为数字
现在我们有一个 CSS 能识别的 length
,但这个单位我们不认识,所以我们要通过 CSS 提供的数学函数计算出真正的数字长度,因此我们要使用 CSS 数学工具中的 atans2(y, x)
和 tan()
。
atans(y, x)
:返回点 (x, y) 到原点的角度(弧度单位)tan()
:返回给定角度的正切
通过上面这两个数学函数,计算 --w_raw
与 --h-raw
到 1px
之间角度的正切值,进而得到宽高的纯数字。
将数字展示到页面
通过 CSS 的计数器将数字展示到页面上。
这其中:
counter(w)
:表示计数器 w 的值counter-reset: w var(--w)
:表示计数器 w 被重置为 --w 的值
body::before {
content: counter(w) 'x' counter(h);
counter-reset: h var(--h) w var(--w);
}
完整代码
@property --w_raw {
syntax: '<length>';
inherits: false;
initial-value: 100vw;
}
@property --h_raw {
syntax: '<length>';
inherits: false;
initial-value: 100vh;
}
:root {
--w: tan(atan2(var(--w_raw), 1px));
--h: tan(atan2(var(--h_raw), 1px));
}
body::before {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
content: counter(w) 'x' counter(h);
counter-reset: h var(--h) w var(--w);
}
复习一下传统开发中的获取方案
JavaScript
在原生 JavaScript 中,我们通过 innerWidth
获取窗口宽度,然后通过监听 resize
变化重新赋值。
let windowWidth = window.innerWidth;
function handleResize = () => windowWidth = window.innerWidth
window.addEventListener('resize', handleResize)
window.addEventListener('resize', handleResize)
Vue
在 Vue3 中,我们可以通过自定义 Hook
的方式实现 resize
。
// useWindowWidth.js
import { ref, onMounted, onUnmounted } from 'vue';
export function useWindowWidth() {
const windowWidth = ref(window.innerWidth);
const handleResize = () => {
windowWidth.value = window.innerWidth;
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
return windowWidth;
}
由于 Vue2 不支持自定义 Hook
,我们则需通过 Mixin
的方式实现。
// windowMixin.js
export const windowMixin = {
data() {
return {
windowWidth: window.innerWidth
};
},
methods: {
handleResize() {
this.windowWidth = window.innerWidth;
}
},
mounted() {
window.addEventListener('resize', this.handleResize);
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
}
};
React
React 也是一个简单的 Hook
。
// useWindowWidth.js
import { useState, useEffect } from 'react';
export function useWindowWidth() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};
// 初始化时调用一次
handleResize();
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
// 清除监听器
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return windowWidth;
}
最后
通过上面文章,相信大家可以学会 CSS 如何实现监听 window 宽度,并且可以举一反三的利用该原理做更多的事情。✌️
同时我们还复习了多种语言中如何监听 window 宽度。
今天的分享就到这里了🙆 ~
你的 点赞、收藏、关注 ,是我继续写下去的唯一动力 ~