代码
import { useState, useEffect } from 'react'
export const getTargetElement = (target, defaultElement = window) => {
if (!target) {
return defaultElement
}
let targetElement;
if (typeof target === 'function') {
targetElement = target()
} else if ('current' in target) {
if (target.current) {
targetElement = target.current
} else {
return defaultElement
}
} else {
targetElement = target
}
return targetElement
}
const useSize = (target) => {
const [state, setState] = useState({
width: 0,
height: 0
})
useEffect(() => {
const targetElement = getTargetElement(target)
if (!targetElement) {
return
}
const observer = new ResizeObserver(function elResizeChange(entries) {
// 每次被观测的元素尺寸发生改变这里都会执行
entries.forEach((entry) => {
const { width, height } = entry.target.getBoundingClientRect()
setState({
width: width,
height: height,
});
});
})
observer.observe(targetElement) // 观测DOM元素
return () => {
observer.disconnect()
}
}, [target])
return {
...state
}
}
export default useSize
demo
import React, { useRef } from 'react'
import useSize from './hooks/useSize'
function App() {
const ref = useRef(null);
const { width, height } = useSize(ref)
return (
<div className="App" style={{textAlign: 'right'}}>
<div ref={ref} style={{
position: 'absolute',
width: '33%',
height: '66%',
background: 'pink'
}}>
123213123
</div>
<div>{width}</div>
<div>{height}</div>
</div>
);
}
export default App;