渲染高度和客户端高度不同

时间:2019-06-23 21:59:36

标签: css reactjs

我有一个react应用程序,其中包含发布卡的react组件。它们代表具有标题,一些作者,摘要,日期和其他某些字段的出版物。我希望每个元素都具有相同的卡片尺寸,并且卡片中的每个元素都要对齐,以便标题部分的高度与最高标题的高度相同,作者的高度与作者的最高高度相同,并且等等。

为此,我有一个内部div,其中包含不应更改其内容的内容,并且我将外部div设置为所有内部div元素中的最高clientHeight。

我有一个调整大小功能,但是仅在您通过调整窗口大小来拖动和移动浏览器时有效。当我单击最大化,还原或将浏览器锁定到屏幕时,它会忽略内部div的高度,并将其设置为怪异的值。即,在chrome调试器中,内容的呈现大小将为85px,但是如果我在设置之前跟踪该值,则clientWidth会针对每个内部div显示所有值,例如28,因此将外部div设置为该值值。

    render() {
        return (
            <PubContainer>
                <TitleSection                        
                    style={{ height: this.state.pubTitleHeight }}>
                        <InnerDiv className="innerPubTitleDiv">
                            {this.props.publicationData.header}                            
                            <SubtitleSection>
                                {this.props.publicationData.subtitle}
                            </SubtitleSection>       
                        </InnerDiv>
                </TitleSection>
            </PubContainer>
        );
    }

SubtitleSection是一个div,InnerDiv是一个容器,其高度应设置为其中的任何值。这里是其余的代码,以及resize函数。

     componentDidUpdate() {        
        this.updatePublicationCardSizes();        
    }

    componentDidMount() {
        this._isMounted = true;

        this.updatePublicationCardSizes();
        window.addEventListener('resize', this.updatePublicationCardSizes.bind(this));
    }

    componentWillUnmount() {
        this._isMounted = false;
        window.removeEventListener('resize', this.updatePublicationCardSizes.bind(this));
    }

    updatePublicationCardSizes() {        
        this.setContainerHeightByClassName('innerPubTitleDiv', 'pubTitleHeight');
    }

    setContainerHeightByClassName(innerDivClassName, stateName) {
        var classNameList = document.getElementsByClassName(innerDivClassName);

        if (classNameList != undefined) {
            var maxHeight = 0;

            for (var index = 0; index < classNameList.length; index++) {
                var divHeight = classNameList[index].clientHeight;

                if (maxHeight < divHeight) {
                    maxHeight = divHeight;
                }
            }

            if (this._isMounted) {
                if (maxHeight > 0) {
                    if (this.state[stateName] != maxHeight) {                        
                    this.setState({
                        [stateName]: maxHeight
                    });
                }
                } else {
                    if (this.state[stateName] != '100%'){
                        this.setState({
                            [stateName]: '100%'
                        });
                    }
                }
            }
        }
    }

我已经确认浏览器的所有更改(拖动,对齐,还原,最大,最小)都将调用调整大小。同样,通过拖动浏览器来更改宽度的正常大小调整确实会正确更新并调整其大小,仅当我单击最大化按钮时,例如,我才获得了奇怪的值。我试图找出为什么仅这些案例不起作用以及如何使它们起作用。

编辑

我已经将代码重构为使用钩子,但单击最大化/还原时仍然遇到相同的问题。显然,内部div clientHeight仍是根据预渲染大小来计算的,而不是在resize事件完成并渲染后进行设置。有什么想法吗?

function PublicationCard(props) {

    const [pubTitleHeight, setTitleHeight] = useState('100%');

    useLayoutEffect(() => {
        updatePublicationCardSizes();
        window.addEventListener("resize", updatePublicationCardSizes);

        return () => window.removeEventListener("resize", updatePublicationCardSizes);
    });

    const updatePublicationCardSizes = () => {
        setTitleHeight(getContainerMaxHeightByClassName('innerPubTitleDiv'));        
    };

    const getContainerMaxHeightByClassName = (innerDivClassName) => {
        var classNameList = document.getElementsByClassName(innerDivClassName);

        if (classNameList != undefined) {
            var maxHeight = 0;

            for (var index = 0; index < classNameList.length; index++) {              
                var divHeight = classNameList[index].clientHeight;

                if (maxHeight < divHeight) {
                    maxHeight = divHeight;
                }
            }

            if (maxHeight > 0) {
                return maxHeight;                
            } else {
                return '100%';                
            }
        }
    };    

    return (
        <PubContainer>
            <a href={`/publications/${props.publicationData.id}`} target="blank">              
                <div
                    style={{ height: pubTitleHeight }}>
                        <div className="innerPubTitleDiv">
                            {props.publicationData.header}                            
                            <span>
                                &nbsp;{props.publicationData.subtitle}
                            </span>       
                        </div>
                </div>
            </a>
        </PubContainer>
    );
}

0 个答案:

没有答案