react实现类控制台拖拽

import React, { useState, useRef, useEffect } from 'react'
import './drag.css'


export default function Drag() {
  const [flag, setFlag] = useState(true)
  const [show, setShow] = useState(false)
  let dragRef = useRef(null)
  function toggleHandle() {
    setFlag(pre => !pre)
  }
  function dragHandle(e) {
    let tabHeight = dragRef.current.style.height.split('p')[0]
    let { height } = document.querySelector('.outerWrapper').getBoundingClientRect()
    let distance = height - e.clientY
    if (distance < 30) {
      dragRef.current.style.height = 30 + 'px'
      return
    }
    if (distance > 300) {
      dragRef.current.style.height = 300 + 'px'
      return
    }
    if (tabHeight >= 30 && tabHeight <= 300) {
      dragRef.current.style.height = height - e.clientY + 'px'
    }
  }
  useEffect(() => {
    window.addEventListener('dragover', (e) => {
      dragHandle(e)
    })
    return () => {
      window.removeEventListener('dragover', null)
    }
  })
  return (
    <>
      <div className="outerWrapper">
        <div className="innerWrapper"
          onMouseOver={() => setShow(true)}
          onMouseOut={() => setShow(false)}
          style={flag ? { height: '30px' } : { height: '300px' }} ref={dragRef}>
          {show && <div className="mock" draggable="true" onDragOver={dragHandle}></div>}
          <div className="toggle" onClick={toggleHandle}>点击切换</div>
        </div>
      </div >
    </>
  )
}
附css代码:
.outerWrapper {
  position: relative;
  width: 98vw;
  height: 100vh;
  /* background-color: #abf; */
  overflow: hidden;
}

.innerWrapper {
  position: absolute;
  width: 98vw;
  /* height: 300px; */
  bottom: 0;
  transition: all 200ms ease;
  z-index: 99;
  background-color: #fab;
  box-shadow: 0 0 10px rgba(204, 204, 204, 0.815);
}

.toggle {
  position: absolute;
  width: 100px;
  top: 0;
  right: 10px;
  background-color: #bfa;
  cursor: pointer;
  z-index: 999;
}

.mock {
  width: 98vw;
  height: 10px;
  position: absolute;
  top: 0;
  background-color: #efefef;
  cursor: row-resize;
}

 精炼版:

import React, { useState, useEffect, useRef } from 'react'
import './drag.css'


export default function Drag() {
  const [flag, setFlag] = useState(true)  //高度的变化
  const [show, setShow] = useState(false) //显示拖动栏
  const keyRef = useRef(false)  //控制鼠标键按下后再拖动tab栏
  const [tabHeight, setTabHeight] = useState(30)
  function toggleHandle() {
    keyRef.current = false
    setFlag(pre => !pre)
  }
  function dragHandle(e) {
    if (keyRef.current) {
      let { height } = document.querySelector('.outerWrapper').getBoundingClientRect()
      let distance = height - e.clientY
      if (distance <= 30) {
        setFlag(true)
        setShow(false)
        setTabHeight(30)
        return
      }
      if (distance >= 300) {
        setShow(false)
        setTabHeight(300)
        return
      }
      setTabHeight(distance)
    }
  }
  useEffect(() => {
    window.addEventListener('mouseup', () => {
      keyRef.current = false
      setShow(false)
    })
    window.addEventListener('mousemove', (e) => {
      dragHandle(e)
    })
    return () => {
      window.removeEventListener('mouseup', null)
      window.removeEventListener('mousemove', null);
    }
  })
  useEffect(() => {
    let height = flag ? 30 : 300
    setTabHeight(height)
  }, [flag])
  return (
    <>
      <div className="outerWrapper">
        <div className="innerWrapper"
          onMouseOver={() => setShow(true)}
          onMouseOut={() => setShow(false)}
          style={{ height: `${tabHeight}px`, transition: ` ${!keyRef.current ? 'all 200ms ease' : 'none'}`, }}>

          <div className="mock"
            ref={keyRef}
            onMouseDown={() => keyRef.current = true}
            style={{ background: `${show ? '#efefef' : 'transparent'}` }}></div>
          <div className="toggle" onClick={toggleHandle}>点击切换</div>
        </div>
      </div >
    </>
  )
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值