It works when I manually resize the window, but not when the content height changes which is what I need.
Am I doing something wrong?
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;
`;
You are observing Container for size change, but it has fixed dimensions:
height: ${({ theme }) => Math.abs(100 - theme.header.height.percent)}%;
// ...
width: ${({ theme }) => 100 - theme.sidebar.width.percent}%;
so it never actually resizes, and resize observer never triggers.
Try wrapping its content inside an element that shrinks to the size of its content, and use the resize observer on this element instead:
this.contentObserver.observe(this.contentRef.current);
// ...
<Container onScroll={this.handleScroll}>
<ShrinkWrapper ref={this.contentRef}>
<Body />
</ShrinkWrapper>
</Container>
const ShrinkWrapper = styled.div`
width: fit-content;
height: fit-content;
`
Solved it by using a MutationObserver with subtree enabled.
this.containerObserver = new MutationObserver(this.handleResize);
this.containerObserver.observe(this.containerRef.current, {
childList: true,
subtree: true,
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With