React魔法堂:size-sensor源碼略讀

前言echarts-for-react在對echarts進行輕量級封裝的基礎上,額外提供圖表尺寸自適應容器尺寸的這小而實用的功能,而這功能的背后就是本文想介紹的size-sensor了 。
源碼介紹【React魔法堂: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 = 0object.style.let = 0object.style.width = '100%'object.style.height = '100%'object.style.pointerEvents = 'none'object.style.zIndex = -1object.style.opacity = 0object.type = 'text/html'target.appendChild(object)object.data = 'https://www.huyubaike.com/biancheng/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兼容方案 - MutationObserverRepos: https://github.com/que-etc/resize-observer-polyfillRepos: https://github.com/juggle/resize-observer
尊重原創 , 轉載請注明來自:https://www.cnblogs.com/fsjohnhuang/p/16814327.html 肥仔John

    推薦閱讀