首页 > 编程语言 >React魔法堂:size-sensor源码略读

React魔法堂:size-sensor源码略读

时间:2022-10-21 17:45:27浏览次数:72  
标签:style 元素 handle target observer object React 源码 略读

前言

echarts-for-react在对echarts进行轻量级封装的基础上,额外提供图表尺寸自适应容器尺寸的这小而实用的功能,而这功能的背后就是本文想介绍的size-sensor了。

源码介绍

size-sensor源码十分精简,主要是对原生APIResizeObserver方案和object元素方案进行检测和API统一化而已。

代码首先会检测当前运行时是否支持原生APIResizeObserver,若不支持则使用object元素方案。下面我们将对两种方案进行探讨。

基于浏览器原生API - ResizeObserver实现

用于监听Element内容盒子或边框盒子或者SVGElement边界尺寸的大小,并调用回调函数。
MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver

/**
 * @param {ResizeObserverEntry} entries - 用于获取每个元素改变后的新尺寸
 * @param {ResizeObserver} observer
 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserverEntry
 */ 
function handleResize(entries, observer) {
  for (let entry of entries) {
    //......
  }
}
const target = document.getElementById('main')

const observer = new ResizeObserver(handleResize)

// 开始对指定DOM元素的监听
observer.observe(target)

// 结束对指定DOM元素的监听
observer.unobserve(target)

// 结束对所有DOM元素的监听
observer.disconnect()

注意:在handleResize中修改target的尺寸并不会导致递归调用handleResize函数。

基于object元素的兼容方案实现

object元素用于内嵌图像、音频、视频、Java applets、ActiveX、PDF和Flash等外部资源,因此其也会像iframe元素那样生成独立的browser context。
而browser context中Window实例的尺寸会保持和object元素的一致,因此可以通过订阅browser context中Window实例的resize事件实现对容器的尺寸的监听。

function bind(target, handle) {
  if (getComputedStyle(target).position === 'static') {
    target.style.position = 'relative'
  }

  let object = document.createElement('object')
  object.onload = () => {
    object.contentDocument.defaultView.addEventListener('resize', handle)
    // 初始化时先触发一次
    handle()
  }
  object.style.display = 'block'
  object.style.position = 'absolute'
  object.style.top = 0
  object.style.let = 0
  object.style.width = '100%'
  object.style.height = '100%'
  object.style.pointerEvents = 'none'
  object.style.zIndex = -1
  object.style.opacity = 0
  object.type = 'text/html'

  target.appendChild(object)
  object.data = 'about:data'

  return () => {
    if (object.contentDocument) {
      object.contentDocument.defaultView.removeEventListener('resize', handle)
    }
    if (object.parentNode) {
      object.parentNode.removeChild(object)
    }
  }
}

这里将object元素替换为iframe元素也是可以的,只需将object.data换成iframe.src即可。
注意:在handle中修改target的尺寸并会导致递归调用handle函数。

ResizeObserver的polyfill兼容方案 - MutationObserver

Repos: https://github.com/que-etc/resize-observer-polyfill
Repos: https://github.com/juggle/resize-observer

尊重原创,转载请注明来自:https://www.cnblogs.com/fsjohnhuang/p/16814327.html 肥仔John

标签:style,元素,handle,target,observer,object,React,源码,略读
From: https://www.cnblogs.com/fsjohnhuang/p/16814327.html

相关文章

  • 还不清楚JDK动态代理?从简单例子到源码再到字节码讲给你听
    一、前言 Spring中的AOP思想就是对代理模式的经典运用,下面先讲讲代理模式的核心思想,以静态代理为例。二、静态代理示例下面有这样一个例子,委托人在遭遇利益受损的时候,可以......
  • GATK源码解析(一)
    程序入口 org.broadinstitute.hellbender.Main类下的main函数publicstaticvoidmain(finalString[]args){newMain().mainEntry(args);}......
  • React相关《下》
    React组件有几种特殊方法,它们提供了在组件生命周期中的特定点执行操作的机会,它们被称为生命周期方法或生命周期钩子,允许我们在特定时间点捕获组件,比如在组件被渲染之前、更......
  • React学习--路由不跳转
    在配置React路由的时候遇到的问题,url跳转了但是页面没有跟着刷新,找了很久没找到问题最后想了想可能是因为index.js的<React.StrictMode>导致的,注释之后就成功了......
  • android Activity的启动流程源码分析
    ActivityThread在handlebindapplication中执行完Application的初始化之后会继续进入到消息循环中接收AMS(activitymanagerservice)启动activity的消息。AMS首先会发送启动......
  • react下载兼容浏览器
    //导出模板exportfunctionexportTemplateExcel(url,params,config={}){returnnewPromise((resolve,reject)=>{axios.get(url,{params:pa......
  • 直播网站源码,React中的三大实例之ref的三种形式
    直播网站源码,React中的三大实例之ref的三种形式ref有三种形式:字符串形式回调函数形式CreateRef形式如下示例代码展示了三种形式ref的创建于使用 <!DOCTYPEhtml><......
  • Java一个还不错的日期格式转换工具类(附源码)
    Java工具类pom依赖<commons-lang3.version>3.3.2</commons-lang3.version><dependency><groupId>org.apache.commons</groupId......
  • 软件绘制源码流程分析
    引言:之前的文章中提到过软件绘制是会调用drawSoftware方法进行绘制的。在这个方法里面调用了Surface.lockCanvas和unlockAndPost方法。这篇文章就分析这两个方法Surface......
  • 基于springboot高考填报志愿综合参考系统设计与实现-计算机毕业设计源码+LW文档
    摘要:高考填报志愿综合参考系统是针对目前高考填报志愿管理的实际需求,从实际工作出发,对过去的高考填报志愿综合参考系统存在的问题进行分析,完善用户的使用体会。采用计算机系......