js 对DOM观察大小改变的处理通知方法。ResizeObserver的应用。

环境

代码示例使用了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()
})

参阅

  1. https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
  2. https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  3. https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver/ResizeObserver
  4. 判断DOM是否溢出可视窗口,出现滚动条的判断几个属性,offsetWidth,clientWidth,scrollWidth
posted @ 2022-11-01 14:39  星小梦  阅读(251)  评论(0编辑  收藏  举报