我正面临一个问题,我什至都不知道是因为ReactJS还是JavaScript。
基本上,如果document.elementsFromPoint()
正在观察DOM的元素,则方法ResizeObserver
不起作用。
这是一个重现问题的小提琴:
class App extends React.Component {
divRef;
resizeObserver;
constructor(props) {
super(props);
this.divRef = React.createRef();
this.resizeObserver = new ResizeObserver(entries => {
console.log("Div resized");
this.forceUpdate();
});
}
componentDidMount() {
console.log("|| DIDMOUNT CONSOLE || ");
console.log(document.elementsFromPoint(150,150));
this.resizeObserver.observe(this.divRef.current);
}
componentDidUpdate() {
console.log("|| DIDUPDATE CONSOLE || ");
console.log(document.elementsFromPoint(150,150));
}
componentWillUnmount() {
this.resizeObserver.unobserve(this.divRef.current);
}
render() {
return (
<div ref={this.divRef} className="home-div" />
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
@import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
.home-div {
background: blue;
width: 500px;
height: 200px;
resize: both;
overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
如您所见,使用componentDidMount()
的{{1}}登录将返回一堆元素。
相反,再次使用document.elementsFromPoint()
的{{1}}登录仅返回componentDidUpdate()
元素,而不返回所有其他元素(即使点完全相同,document.elementsFromPoint()
)
现在,我认为React以某种方式重新渲染了整个DOM,因此,以前的内容不再存在于DOM中,但是html
不可能只返回(150, 150)
元素:渲染完成后,componentDidUpdate()
被称为,因此不可能只有html
元素。
这是一个错误吗?还是我在某处缺少什么?
答案 0 :(得分:1)
我想这是一个错误。显然,当document.elementsFromPoint()
仅返回HTML元素时,在文档的某些奇怪状态下调用了观察者回调。您甚至不需要调用this.forceUpdate()
,而直接在观察者回调内部调用elementsFromPoint
,您将获得相同的结果。每次调整div的大小时,我都会得到相同的结果。
我认为componentDidUpdate
记录的日志相同,因为forceUpdate
-> render
-> DOM更新-> componentDidUpdate
调用链是同步的,并且这种奇怪的DOM状态仍然存在。好吧,可能是DOM状态仅对elementsFromPoint
调用很奇怪...
例如,如果您使用forceUpdate
异步调用setTimeout
,则elementsFromPoint
将正确显示所有div。