反应:使div的宽度等于高度。高度计算不正确

Posted

技术标签:

【中文标题】反应:使div的宽度等于高度。高度计算不正确【英文标题】:React: Making width of div equal to height. The height is not being calculated correctly 【发布时间】:2020-11-20 16:58:56 【问题描述】:

Github repo of this project


基于我看到的其他解决方案,我创建了一个组件,该组件应该计算其子项的宽度和高度,然后将宽度和高度设置为等于长度中的任何一个一个更长。

Ex.如果width=30,height=20,则设置width和height为30。如果height为30,width为20,结果应该是一样的。

    import React, useState, useEffect, useRef from 'react';
    
    const SymmetricalDiv = (style, children, ...props) => 
        const [diamStyle, setDiamStyle] = useState();
        const elementRef = useRef(null);
        style = style ? Object.assign(, diamStyle, style) : diamStyle ;
    
        useEffect(() => 
            const width = elementRef.current.clientWidth;
            const height = elementRef.current.clientHeight;
            const diam = Math.max(width, height);   
            setDiamStyle(width: diam, height: diam);
        , []);
    
        return (
            <div ref=elementRef ...props style=style>
                children
            </div>
        );
    ;

这是我尝试使用此组件的示例。 (样式是使用引导程序完成的)

    import React from 'react';
    import SymmetricalDiv from 'components/Styled'
    import svgLogo from 'src/SVG_logo.svg'

    const MyComponent = () => 
        return (
            <SymmetricalDiv className='rounded-circle d-flex flex-column align-items-center bg-danger'>
                <strong >A title</strong>
                <span>A description</span>
                <img className='my-3' src=svgLogo />
                <a href="#">A Link</a>
            </SymmetricalDiv>
        );
    ;

此示例产生以下结果。它错误地计算了高度,并认为宽度是较长的尺寸。然后将宽度和高度设置为等于宽度,这就是为什么一些孩子出现在圆圈之外的原因。

【问题讨论】:

也将样式设置为状态。 @WilliamWang 这不会改变任何事情,对不起 【参考方案1】:

它与高度/宽度不匹配的原因似乎是因为您的图像没有设置高度/宽度。

没有设置高度/宽度的图像最初以 0 宽度/高度开始,这是您进行计算的地方。然后加载图像并进行回流。

有两种简单的方法可以解决您的问题:

设置图片的宽度

这可以确保图像在完全加载之前知道它的高度/宽度。

<SymmetricalDiv className="rounded-circle d-flex flex-column align-items-center bg-danger">
  <strong>A title</strong>
  <span>A description</span>
  <img className="my-3"   src=svgLogo />
  <a href="#">A Link</a>
</SymmetricalDiv>

内联 SVG/使其成为组件

这完全消除了图像的加载步骤。

// SVGLogo.js

export default () => 
  return <svg>...</svg>

// App.js

<SymmetricalDiv className="rounded-circle d-flex flex-column align-items-center bg-warning">
  <strong>A title</strong>
  <span>A description</span>
  <SVGLogo />
  <a href="#">A Link</a>
</SymmetricalDiv>

您可以在 Code Sandbox example 中看到这两种实现的实际应用

明确图像的大小对于确保您的应用按预期运行非常有帮助。

您还可以阅读有关preventing reflow due to image loading的更多信息

【讨论】:

对于内联,你知道如何使用 webpack 加载器来做到这一点吗?看起来raw-loader 可能是要走的路,但是当我将test: /\.svg$/, use: ['raw-loader',] 添加到我的webpack.config.js 时,我得到的错误看起来像Cannot find module 'images/svg/myImage.svg' from 'C:\codebase\src\components\myComponent' npmjs.com/package/@svgr/webpack 将是一个非常好的选择。它还优化了 svg,这是一个奖励。 如何让它导入我的图像?现在我收到react-dom.development.js:22665 Uncaught DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('/images/my-svg.svg') is not a valid name Images 是我在 webpack 中创建的快捷方式 'images': path.resolve(__dirname + '/src/assets/images'), 因为我的webpack.config.js 中还有test: /\.(gif|png|jpe?g|svg)$/i, use: [ 'file-loader?name=images/[name].[ext]'

以上是关于反应:使div的宽度等于高度。高度计算不正确的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ionic 中使元素的高度等于其宽度?

如何计算移动设备的宽度和高度

如何使div中的图片自适应宽度和高度,图片不变形,可以超出div,超出部分隐藏

高度等于视口的方形 DIV

Jquery 将每个选定的 div 高度设置为等于其宽度

如何在 CSS Grid 中使 div 高度等于宽度