zoukankan      html  css  js  c++  java
  • react 可拖拽改变位置和大小的弹窗

    一 目标

     最近,项目上需要一个可以弹出一个可以移动位置和改变大小的窗口,来显示一下对当前页面的一个辅助内容

    二 思路

     1.之前写过一个antd modal的可移动弹窗但是毕竟不如自己写的更定制化,比如不需要显示遮罩层,但是移动的思想一致都是鼠标的按下和抬起事件以及坐标位置来计算改变弹窗位置.

     2.窗口的的小调节可以用css的resize属性,当然也可以自己写一个指定边框拖拽调整大小的功能,后期可能会更新

    三 代码内容

     index.js

     1 import React, { Component } from 'react'
     2 import { Icon } from 'antd'
     3 import style from './index.less'
     4 class PopContainer extends Component {
     5     constructor(props) {
     6         super(props);
     7         this.windowH = document.body.clientHeight;
     8         this.windowW = document.body.clientWidth;
     9         this.state = {
    10             styleTop: 20,
    11             styleLeft: 10,
    12             styleHeight: props.height || this.windowH * 0.85,
    13             styleWidth: props.width || this.windowW * 0.45,
    14         }
    15     }
    16   //计算是否超出屏幕
    17     InWindow = (left, top, startPosX, startPosY) => {
    18         let H = document.body.clientHeight;
    19         let W = document.body.clientWidth;
    20         if ((left < 20 && startPosX > left) || (left > W - 20 && startPosX < left) ||
    21             (top < 20 && startPosY > top) || ((top > H - 20 && startPosY < top))) {
    22             return false
    23         }
    24         return true
    25     }
    26     onMouseDown = e => {
    27         e.preventDefault();
    28         let startPosX = e.clientX;
    29         let startPosY = e.clientY;
    30         const { styleLeft, styleTop } = this.state;
    31         document.body.onmousemove = e => {
    32             let left = e.clientX - startPosX + styleLeft;
    33             let top = e.clientY - startPosY + styleTop;
    34             if (this.InWindow(e.clientX, e.clientY, startPosX, startPosY)) {
    35                 this.setState({
    36                     styleLeft: left,
    37                     styleTop: top,
    38                 })
    39             } else {
    40                 document.body.onmousemove = null;
    41                 document.body.onmouseup = null;
    42             }
    43         };
    44         document.body.onmouseup = function () {
    45             document.body.onmousemove = null;
    46             document.body.onmouseup = null;
    47         };
    48     };
    49     render() {
    50         const { styleLeft, styleTop, styleHeight, styleWidth } = this.state
    51         const { visible, onClose, children, bodyStyle, title } = this.props
    52         return <div className={style.popContainer} style={{
    53             display: visible ? "block" : "none",
    54             left: styleLeft + 'px', top: styleTop + 'px',
    55         }}>
    56             <div className={style.header}>
    57                 <div className={style.title} onMouseDown={this.onMouseDown} >{title}</div>
    58                 <span className={style.close} onClick={onClose}><Icon type="close" /></span>
    59             </div>
    60             <div className={style.content} style={{ ...bodyStyle }}>
    61                 {children}
    62             </div>
    63             <div className={style.footer}>
    64             </div>
    65         </div>
    66 
    67     }
    68 }
    69 
    70 export default PopContainer;

    index.less

    .popContainer {
        position        : fixed;
        width           : 50vw;
        height          : 80vh;
        background-color: white;
        z-index         : 200;
        box-shadow      : 0px 4px 12px 0px rgba(0, 0, 0, 0.45);
        border-radius   : 4px;
        resize          : both;
        overflow        : auto;
        min-width       : 200px;
        min-height      : 60px;
    
        .header {
            padding      : 16px 24px;
            color        : rgba(0, 0, 0, 0.65);
            border-bottom: 1px solid #e8e8e8;
            border-radius: 4px 4px 0 0;
    
            .close {
                position   : absolute;
                top        : 0;
                right      : 0;
                cursor     : pointer;
                width      : 56px;
                height     : 56px;
                font-size  : 16px;
                line-height: 56px;
                text-align : center;
                color      : rgba(0, 0, 0, 0.45);
    
                &:hover {
                    color: black;
                }
            }
    
            .title {
                cursor     : move;
                color      : rgba(0, 0, 0, 0.85);
                font-weight: 500;
                font-size  : 16px;
                line-height: 22px;
            }
        }
    
        .content {
            height    : calc(100% - 70px);
            overflow-y: scroll;
            padding   : 24px;
        }
    
    }

    引用的文件

     import PopContainer from './PopContainer/index.js'
      ...
     onShow = ()=>{
         this.setState({visible:true})
     }
     onClose=()=>{
        this.setState({visible:false})
     }
     render(){
          <Button  onClick={this.onShow}>打开弹窗</Button>
          <PopContainer  visible={this.state.visible} onClose={this.onClose} title="标题" >
         内容  
        <PopContainer /> 
    }
  • 相关阅读:
    扫描线算法模板
    spark submit 常用设置
    networkx 画有向图 使用DiGraph
    超实用的Spark数据倾斜解决
    解决spark中遇到的数据倾斜问题
    TrickBot 恶意木马软件
    windows 打开snappy文件 安装python snappy——还是直接用pip install xx.whl 打包好的安装吧
    解决CentOS删除文件后没有释放磁盘空间(lsof命令)
    Linux 系统下 centOS 7 ipconfig 提示没有安装
    tomcat启动报错org.apache.catalina.LifecycleException: The configured protocol [org.apache.coyote.http...
  • 原文地址:https://www.cnblogs.com/ITCoNan/p/13718799.html
Copyright © 2011-2022 走看看