内容高度更改时未触发 ResizeObserver(反应)
ResizeObserver not being triggered when content height changes (React)
当我手动调整 window 大小时它起作用,但当内容高度发生变化时不起作用,这正是我需要的。
我是不是做错了什么?
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.containerRef = React.createRef();
this.containerObserver = null;
this.state = {
top: false,
};
}
componentDidMount() {
this.containerObserver = new ResizeObserver((e) => this.handleResize(e));
this.containerObserver.observe(this.containerRef.current);
}
componentWillUnmount() {
if (this.containerObserver) {
this.containerObserver.disconnect();
}
}
handleResize = (e) => {
const { target } = e[0];
const top = target.scrollTop;
const scrollHeight = target.scrollHeight;
const position = scrollHeight - top;
const clientHeight = target.clientHeight;
console.log({ top }, { scrollHeight }, { position }, { clientHeight });
if (top < 10) {
if (this.state.top) {
this.setState({ top: false });
}
} else {
if (!this.state.top) {
this.setState({ top: true });
}
}
if (position >= clientHeight - 40 && position <= clientHeight) {
if (!this.state.top) {
this.setState({ top: true });
}
}
};
render() {
return (
<React.Fragment>
<Container ref={this.containerRef} onScroll={this.handleScroll}>
<Body />
</Container>
<ShadowTop show={this.state.top} />
</React.Fragment>
);
}
}
--
export const Container = styled.div`
@media (max-width: 760px) {
position: absolute;
}
margin-top: ${({ theme }) => theme.header.height.percent}%;
margin-top: -webkit-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: -moz-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: calc(${({ theme }) => theme.header.height.pixel}px);
height: ${({ theme }) => Math.abs(100 - theme.header.height.percent)}%;
height: -webkit-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: -moz-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: calc(100% - ${({ theme }) => theme.header.height.pixel}px);
position: fixed;
float: none;
clear: both;
top: 0;
right: 0;
width: ${({ theme }) => 100 - theme.sidebar.width.percent}%;
width: -webkit-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: -moz-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
z-index: 2;
pointer-events: auto;
overflow: auto;
`;
使用启用了 subtree
的 MutationObserver
解决了这个问题。
this.containerObserver = new MutationObserver(this.handleResize);
this.containerObserver.observe(this.containerRef.current, {
childList: true,
subtree: true,
});
当我手动调整 window 大小时它起作用,但当内容高度发生变化时不起作用,这正是我需要的。
我是不是做错了什么?
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.containerRef = React.createRef();
this.containerObserver = null;
this.state = {
top: false,
};
}
componentDidMount() {
this.containerObserver = new ResizeObserver((e) => this.handleResize(e));
this.containerObserver.observe(this.containerRef.current);
}
componentWillUnmount() {
if (this.containerObserver) {
this.containerObserver.disconnect();
}
}
handleResize = (e) => {
const { target } = e[0];
const top = target.scrollTop;
const scrollHeight = target.scrollHeight;
const position = scrollHeight - top;
const clientHeight = target.clientHeight;
console.log({ top }, { scrollHeight }, { position }, { clientHeight });
if (top < 10) {
if (this.state.top) {
this.setState({ top: false });
}
} else {
if (!this.state.top) {
this.setState({ top: true });
}
}
if (position >= clientHeight - 40 && position <= clientHeight) {
if (!this.state.top) {
this.setState({ top: true });
}
}
};
render() {
return (
<React.Fragment>
<Container ref={this.containerRef} onScroll={this.handleScroll}>
<Body />
</Container>
<ShadowTop show={this.state.top} />
</React.Fragment>
);
}
}
--
export const Container = styled.div`
@media (max-width: 760px) {
position: absolute;
}
margin-top: ${({ theme }) => theme.header.height.percent}%;
margin-top: -webkit-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: -moz-calc(${({ theme }) => theme.header.height.pixel}px);
margin-top: calc(${({ theme }) => theme.header.height.pixel}px);
height: ${({ theme }) => Math.abs(100 - theme.header.height.percent)}%;
height: -webkit-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: -moz-calc(100% - ${({ theme }) => theme.header.height.pixel}px);
height: calc(100% - ${({ theme }) => theme.header.height.pixel}px);
position: fixed;
float: none;
clear: both;
top: 0;
right: 0;
width: ${({ theme }) => 100 - theme.sidebar.width.percent}%;
width: -webkit-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: -moz-calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
width: calc(100% - ${({ theme }) => theme.sidebar.width.pixel}px);
z-index: 2;
pointer-events: auto;
overflow: auto;
`;
使用启用了 subtree
的 MutationObserver
解决了这个问题。
this.containerObserver = new MutationObserver(this.handleResize);
this.containerObserver.observe(this.containerRef.current, {
childList: true,
subtree: true,
});