环境
代码示例使用了VUE3的setup的语法糖。
代码
// 这里使用弱引用
// key是DOM实例
// value是溢出的结果,true标识溢出,false标识没有溢出。
const overflowResultMap = reactive(new WeakMap());
const handlerSizeChange = (target) => {
console.log("handlerSizeChange",target);
// dom的总内容的宽度,包含被剪切的元素的宽度。参阅引用4文档
let scrollWidth = target.scrollWidth
// dom的可视区域。参阅引用4文档
let clientWidth = target.clientWidth
// 当内容宽度和总宽度不一样,则设置为已经溢出了。
if(scrollWidth > clientWidth){
// 当内容的总宽度大于可视区域的宽度,说明这个元素溢出了。可以根据这个进行判断一些场景的处理方法。
overflowResultMap.set(target, true)
}else{
overflowResultMap.set(target, false)
}
}
// 获取菜单的根DOM实例
let rootMenu = ref()
onMounted(()=>{
ApiPromise.then(()=>{
// 这里当api接口返回,页面渲染完成,这里的进行判断下是否初始加载页面已经符合这个条件了
// 因为如果你的页面使用了min-width属性限制最小宽度了,当页面已经处于最小宽度以内,ResizeObserver监听的回调不会被触发执行。
nextTick(()=>{
// 初始状态进行判断下
handlerSizeChange(rootMenu.value)
})
})
})
let resizeObserver = new ResizeObserver((entries, observer) => {
entries.forEach(entry => {
let target = entry.target
console.log("ResizeObserver",target);
handlerSizeChange(target)
})
})
// 这里再对应的位置进行观察dom和取消观察。
onMounted(()=>{
resizeObserver.observe(rootMenu.value, {
box: 'border-box'
})
})
onUnmounted(()=>{
resizeObserver.unobserve(rootMenu.value)
// 断开连接会把resizeObserver实例观察的多个DOM都给断开观察,切记。
resizeObserver.disconnect()
})
参阅
- https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
- https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
- https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver/ResizeObserver
- 判断DOM是否溢出可视窗口,出现滚动条的判断几个属性,offsetWidth,clientWidth,scrollWidth