将 style.transform 设置为父组件后模态(子组件)的行为发生奇怪变化

Strange change in the behavior of a modal (child component) after setting style.transform to the parent component

我遇到了模态框外观或行为的奇怪变化。模态框用于放大聊天中发送的图像。聊天上传预览 div 是父元素,而模态是子元素。在我使用某些功能使聊天上传预览可拖动后,这种奇怪的行为开始发生。在正常情况下,模态框会扩展并覆盖整个屏幕,超出上传预览(父组件)的边界。但是,当通过向其添加 transform/translate CSS 属性 使聊天上传预览可拖动时,模式只会扩展并覆盖上传预览器(父元素)的高度和宽度。有趣的是,如果我删除这个可拖动功能 (transform/translate),模态将恢复正常行为,一直扩展到屏幕边缘。我想知道为什么在父组件的样式中添加 transform/translate CSS 属性 会影响子组件的行为。这让我很困惑。请帮忙。

如果没有 transform/translate 添加到父组件(聊天上传预览 div),它通常看起来是这样的:

下面是将 transform/translate 属性 添加到父组件(聊天上传预览 div)后开始查找的方式:

这是聊天上传预览(父级)的 JSX 代码。模态存在于 FilePreview 组件中,其代码也在下方。

{/* CHAT-UPLOAD-PREVIEW */}                        
{
    this.state.chatFiles.length > 0 ? 

    <div className="chat-upload-preview-1"
    ref={this.myUploader}
    onMouseMove={this.onMouseMove}
    onMouseDown = {() => {this.setState({pressed: true})}}
    onMouseUp = {() => {this.setState({pressed: false})}}
    >


        <p className="close-button-1" onClick={this.closeUploadPreview}>&#10006;</p>

    <h3 className="chat-upload-preview-title-1">Preview</h3>

    <div className="file-preview-div-1">**<FilePreview files={this.state.chatFiles} 
    deletePreviewfile={this.deletePreviewfile2}
    getReadableFileSizeString={this.getReadableFileSizeString}
    /> </div>**
    
    <div className='chat-upload-container-1'>
    <img src='/images/chat-upload.jpg' alt="upload" height="70" 
    width="70" className='chat-upload-3' onClick={this.inputClick2}>                         
    </img>
                <input className="file-input" type="file" name="file" id="file-1"
                onChange={this.handleChange2} multiple 
                accept=".jpg, .jpeg, .png, .pdf, .doc, .docx"></input> 

                <button className="chat-upload-send-button-1" onClick={this.sendImageToChat}>Send</button>  
    </div> 
    
    </div>
    :
    null

}     

这是 FilePreview 组件的代码,它也包含模态代码(在底部)。

import React from 'react'
import './FilePreview.css'

function FilePreview(props) {
    return (
        <div className="image-preview-container">

                            <ul className="image-preview-list">
                            {props.files.map((item) =>                           
                           

                                <li className="image-preview-listItem" key={item.name}>
                                            
                                                                                  
                                            {item.type === "application/pdf"  ?
                                            
                                                // PDF


                                            <div className="pdf-file" >

                                          
                                        <iframe src={URL.createObjectURL(item)} className="iframe-pdf"
                                            height="110" width="100" title="pdf-review">
                                                </iframe>

                                            <a className="pdf-link" href={URL.createObjectURL(item)} target="_blank">view pdf</a>

                                                 <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                <p className="file-name">{item.name}</p> 
                                <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>    
                                            </div>
                                            
                                            :

                                                    // WORD

                                                                                    
                                            item.type === "application/msword" ?

                                            <div className="pdf-file" >
                                                

                                                <img className="document-image" src="images\msword.png" alt="your file" height="50" width="50"/> 

                                                    
                                            <a className="pdf-link" href={URL.createObjectURL(item)} target="_blank">download to view</a>

                                        <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                <p className="file-name">{item.name}</p> 
                                <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>
                                            </div>

                                            :

                                                    // WORD docx

                                            item.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ?

                                            <div className="pdf-file" >
                                                

                                                <img className="document-image" src="images\msword.png" alt="your file" height="50" width="50"/> 

                                                    
                                            <a className="pdf-link" href={URL.createObjectURL(item)} target="_blank">download to view</a>

                                        <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                <p className="file-name">{item.name}</p> 
                                <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>    
                                            </div>

                                            :

                                                        // Image - Jpeg    

                                            item.type === "image/jpeg" ?   

                                                        

                                            <div className="image-file">

                                          {console.log(URL.createObjectURL(item))}

                                                <img className="document-image" src={URL.createObjectURL(item)} alt="your file" height="50" width="50" 
                                    
                                    onClick={() => {
                                        
                                        const modal = document.getElementById("myModal");
                                        const modalImg = document.getElementById("img01");

                                        modal.style.display = "block";
                                        modalImg.src = URL.createObjectURL(item);

                                    }}>

                                    </img>

                                        <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                    <p className="file-name">{item.name}</p> 
                                    <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>     

                                            </div>

                                            :
                                                        // Image - png

                                            item.type === "image/png" ?                                               

                                            <div className="image-file">

                                            {console.log(URL.createObjectURL(item))}

                                                <img className="document-image" src={URL.createObjectURL(item)} alt="your file" height="50" width="50" 

                                            onClick={() => {

                                            const modal = document.getElementById("myModal");
                                            const modalImg = document.getElementById("img01");

                                            modal.style.display = "block";
                                            modalImg.src = URL.createObjectURL(item);

                                            }}>

                                            </img>

                                            <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                            <p className="file-name">{item.name}</p> 
                                            <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>     

                                            </div>

                                            :

                                                         // Others to be added

                                            <div className="image-file">
                                                <img className="document-image" src={URL.createObjectURL(item)} alt="your file" height="50" width="50" 
                                    
                                    onClick={() => {
                                        
                                        const modal = document.getElementById("myModal");
                                        const modalImg = document.getElementById("img01");

                                        modal.style.display = "block";
                                        modalImg.src = URL.createObjectURL(item);

                                    }}>

                                    </img>

                                        <button className="document-image-deleter" onClick={() => props.deletePreviewfile(item)}>x</button>

                                    <p className="file-name">{item.name}</p> 
                                    <p className="file-size">{props.getReadableFileSizeString(item.size)}</p>     

                                            </div>


                                                                                    
                                                                                
                                            }
                                    
                                    


                                    {/* The Image PopUp */}

                                    <div id="myModal" className="modal">

                                                                                  
                                        {/* the close button (x) */}
                                        <span className="close" onClick={() => {
                                            const modal = document.getElementById("myModal");
                                            modal.style.display = "none";
                                        }}>&times;</span>

                                        {/* the image itself */}
                                        <img className="modal-content" id="img01" alt="Something"></img>

                                        {/* Text needs to be added */}
                                        <div id="caption"></div>

                                    </div>


                                </li>
                            )}                                                

                        </ul>                                    
            
        </div>
    )
}

export default FilePreview

这里又是模态的 JSX:

 {/* The Image PopUp */}

                                    <div id="myModal" className="modal">

                                                                                   
                                        {/* the close button (x) */}
                                        <span className="close" onClick={() => {
                                            const modal = document.getElementById("myModal");
                                            modal.style.display = "none";
                                        }}>&times;</span>

                                        {/* the image itself */}
                                        <img className="modal-content" id="img01" alt="Something"></img>

                                        {/* Text needs to be added */}
                                        <div id="caption"></div>

                                    </div>

这里是添加transform/translate 属性拖拽聊天上传预览的功能。它似乎是模态奇怪行为的罪魁祸首,因为当我删除它时,模态再次表现良好。

componentDidUpdate () {

        if (this.myUploader.current) {
          this.myUploader.current.style.transform = `translate(${this.state.position.x}px, ${this.state.position.y}px)`
          document.onmouseup = () => {this.setState({pressed: false})}
               
        }
      
        
      }

这是聊天上传预览的(父组件)CSS:

.chat-upload-preview-1 {
    position: absolute;
    bottom: 30px;
    left: 300px;
    background-color: blanchedalmond;
    width: 330px;
    height: 600px;
    border-radius: 20px;
    opacity: 0.9;

}

这是模态的 css:

/* The Modal (background) */
.modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1; /* Sit on top */
    padding-top: 100px; /* Location of the box */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0, 0, 0); /* Fallback color */
    background-color: rgba(0, 0, 0, 0.9); /* Black w/ opacity */
    
  }
  
  /* Modal Content (image) */
  .modal-content {
    margin: auto;
    display: block;
    width: 80%;
    max-width: 700px;
  }
  
  /* Caption of Modal Image */
  #caption {
    margin: auto;
    display: block;
    width: 80%;
    max-width: 700px;
    text-align: center;
    color: #ccc;
    padding: 10px 0;
    height: 150px;
  }
  
  /* Add Animation */
  .modal-content,
  #caption {
    -webkit-animation-name: zoom;
    -webkit-animation-duration: 0.6s;
    animation-name: zoom;
    animation-duration: 0.6s;
  }
  
  @-webkit-keyframes zoom {
    from {
      -webkit-transform: scale(0);
    }
    to {
      -webkit-transform: scale(1);
    }
  }
  
  @keyframes zoom {
    from {
      transform: scale(0);
    }
    to {
      transform: scale(1);
    }
  }

我只是不知道一旦上传预览添加了 transform/translate 属性 模态框会发生什么。为什么它不会像添加 transform/translate 属性 之前那样充分扩​​展?我完全不解。

所以,我自己找到了答案。答案在关于转换的 MDN 文章中:https://developer.mozilla.org/en-US/docs/Web/CSS/transform

答案:如果变换 属性 的值不同于 none,将创建一个堆叠上下文。在这种情况下,该元素(具有变换 属性 的元素)将充当任何位置的包含块:固定;或位置:绝对;它包含的元素(模态div)。

问题确实出在转换 CSS 函数中。事实证明,Transform 将可拖动元素更改为一个包含块,该块将其内部的所有元素限制在其尺寸限制内。换句话说,所有内部元素都不会大于它的高度或宽度。

更具体地说,Modal div 没有展开以填满整个屏幕,因为变换 属性 是在拖动时添加到 FilePreview 组件的。结果,image-preview-container div(父元素)成为模态 div(子元素)的包含块,将其限制在其 limits/margins.[=11= 内]

因此,解决方法是在单击图像时从包含块中删除变换 属性,以便它可以像以前一样填满整个屏幕:

if (props.myUploader) { props.myUploader.current.style.transform = 'none' }