关于javascript:React魔法堂sizesensor源码略读

44次阅读

共计 2032 个字符,预计需要花费 6 分钟才能阅读完成。

前言

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

源码介绍

size-sensor源码非常精简,次要是对原生 APIResizeObserver计划和 object 元素计划进行检测和 API 统一化而已。

代码首先会检测以后运行时是否反对原生 APIResizeObserver,若不反对则应用 object 元素计划。上面咱们将对两种计划进行探讨。

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

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

/**
 * @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/re…
Repos: https://github.com/juggle/res…

尊重原创,转载请注明来自:https://www.cnblogs.com/fsjoh… 肥仔 John

正文完
 0