echarts-for-react在對echarts進行輕量級封裝的基礎上,額外提供圖表尺寸自適應容器尺寸的這小而實用的功能,而這功能的背後就是本文想介紹的size-sensor了。
size-sensor原始碼十分精簡,主要是對原生APIResizeObserver
方案和object
元素方案進行檢測和API統一化而已。
程式碼首先會檢測當前執行時是否支援原生APIResizeObserver
,若不支援則使用object
元素方案。下面我們將對兩種方案進行探討。
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
歡迎新增我的公眾號一起深入探討技術手藝人的那些事!
如果您覺得本文的內容有趣就掃一下吧!捐贈互勉!