ElementsFromPoints不适用于ResizeObserver

时间:2019-03-27 09:03:45

标签: javascript reactjs

我正面临一个问题,我什至都不知道是因为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元素。

这是一个错误吗?还是我在某处缺少什么?

1 个答案:

答案 0 :(得分:1)

我想这是一个错误。显然,当document.elementsFromPoint()仅返回HTML元素时,在文档的某些奇怪状态下调用了观察者回调。您甚至不需要调用this.forceUpdate(),而直接在观察者回调内部调用elementsFromPoint,您将获得相同的结果。每次调整div的大小时,我都会得到相同的结果。

我认为componentDidUpdate记录的日志相同,因为forceUpdate-> render-> DOM更新-> componentDidUpdate调用链是同步的,并且这种奇怪的DOM状态仍然存在。好吧,可能是DOM状态仅对elementsFromPoint调用很奇怪...

例如,如果您使用forceUpdate异步调用setTimeout,则elementsFromPoint将正确显示所有div。