前言

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

React魔法堂:size-sensor源码略读的更多相关文章

  1. React魔法堂:echarts-for-react源码略读

    前言 在当前工业4.0和智能制造的产业升级浪潮当中,智慧大屏无疑是展示企业IT成果的最有效方式之一.然而其背后怎么能缺少ECharts的身影呢?对于React应用而言,直接使用ECharts并不是最高 ...

  2. JS魔法堂:jsDeferred源码剖析

    一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...

  3. JS魔法堂:剖析源码理解Promises/A规范

    一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...

  4. JS魔法堂:mmDeferred源码剖析

    一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见 ...

  5. java基础集合类——ArrayList 源码略读

    ArrayList是java的动态数组,底层是基于数组实现. 1. 成员变量 public class ArrayList<E> extends AbstractList<E> ...

  6. react 中间件相关的一些源码解析

    零.随便说说中间件 在react的使用中,我们可以将数据放到redux,甚至将一些数据相关的业务逻辑放到redux,这样可以简化我们组件,也更方便组件抽离.封装.复用,只是redux不能很好的处理异步 ...

  7. React Native 4 for Android源码分析 一《JNI智能指针之介绍篇》

    文/ Tamic: http://blog.csdn.net/sk719887916/article/details/53455441 原文:http://blog.csdn.net/eewolf/a ...

  8. JS魔法堂:IMG元素加载行为详解

    一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...

  9. React源码解析:setState

    先来几个例子热热身: ......... constructor(props){ super(props); this.state = { index: 0 } } componentDidMount ...

随机推荐

  1. 万答#3,MGR最佳配置参考,PFS里的监测指标要全开吗,mysqld进程占用内存过高怎么排查

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 问题1,有推荐的MGR运行最佳配置参考吗 在「3306π」社区广州站5月22日的分享会上,万里数据库CTO娄帅给出了他建议 ...

  2. 【springcloud】环境搭建与Rest使快速上手

    SpringCloud环境搭建 --- Rest使用 个人主页:https://www.cnblogs.com/xbudian/ 今天来到SpringCloud的学习,我们从spring boot微服 ...

  3. HTTP的三次握手和四次挥手,以及DNS流程解析

    首先模拟一个场景:你在浏览器输入自己想要访问的地址,浏览器发送请求到服务端,服务端进行响应,浏览器进行数据页面渲染,从而你得到自己想要访问地址的页面 总体流程图: DNS:可以认为域名与对应的ip转化 ...

  4. MySQL主从-报错

    安装: 环境: 系统:centos7 x3 master:192.168.220.133 slave1:192.168.220.136 slave2:192.168.220.137 mysql服务器, ...

  5. 436. 寻找右区间--LeetCode_暴力

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-right-interval 著作权归领扣网络所有.商业转载请联系官方授权,非商业转载请注明出 ...

  6. jbd2的死锁分析

    已经运行多年的jbd2,它还是死锁了 背景:这个是在centos7的环境上复现的,内核版本为3.10.0-957.27.2.el7 下面列一下我们是怎么排查并解这个问题的. 一.故障现象 oppo云内 ...

  7. 【java】学习路线11-四种权限修饰的测试

    package com.remoo.test;public class Learn09_Test{    private static String welcomeWord1 = "你好,p ...

  8. 快速搭建 SpringCloud Alibaba Nacos 配置中心!

    Spring Cloud Alibaba 是阿里巴巴提供的一站式微服务开发解决方案,目前已被 Spring Cloud 官方收录.而 Nacos 作为 Spring Cloud Alibaba 的核心 ...

  9. Think PHP 完整的带富文本格式以及图片上传,并且在页面上分页展示

    Think php6.0官网网址:序言 · ThinkPHP6.0完全开发手册 · 看云 (kancloud.cn) 下面是基础配置 第一步:创建TP框架,命名为tp composer create- ...

  10. OpenJudge 1.5.24 正常血压

    24:正常血压 总时间限制: 1000ms 内存限制: 65536kB 描述 监护室每小时测量一次病人的血压,若收缩压在90 - 140之间并且舒张压在60 - 90之间(包含端点值)则称之为正常,现 ...