欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React拖拽調(diào)整大小的組件

 更新時(shí)間:2022年08月25日 16:34:53   作者:微笑碼客  
這篇文章主要為大家詳細(xì)介紹了React拖拽調(diào)整大小的組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了React拖拽調(diào)整大小的組件,供大家參考,具體內(nèi)容如下

一、實(shí)現(xiàn)流程

1.使用React.cloneElement加強(qiáng)包裹組件,在包裹的組件設(shè)置絕對(duì)定位,并在組件內(nèi)加上四個(gè)可調(diào)整大小的拖動(dòng)條,在點(diǎn)擊拖動(dòng)條并進(jìn)行拖動(dòng)時(shí)會(huì)改變DragBox的大小,如下:

2.使用:

<DragBox dragAble={true} minWidth={350} minHeight={184} edgeDistance={[10, 10, 10, 10]} dragCallback={this.dragCallback} >
?? ?{/* 使用DragBox拖動(dòng)組件包裹需要調(diào)整大小的盒子 */}
? ?<div style={{ top: 100 + 'px', left: 100 + 'px', width: 350, height: 184, backgroundColor: "white" }}>
? ? ? ? <div style={{ backgroundColor: "yellow", width: "100%", height: 30 }}></div>
? ? ? ? <div style={{ backgroundColor: "green", width: "100%", height: 30 }}></div>
? ? ? ? <div style={{ backgroundColor: "blue", width: "100%", height: 30 }}></div>
? ? </div>
</DragBox>

二、代碼

DragBox組件

import React, { Component, Fragment } from 'react';
import styles from "./DragBox.less";

/**
?* 拖拽的公共組件
?* 接收參數(shù):
?* ? ? ?dragAble:是否開啟拖拽
?* ? ? ?minWidth:最小調(diào)整寬度
?* ? ? ?minHeight:最小調(diào)整高度
?* ? ? ?edgeDistance:數(shù)組,拖拽盒子里瀏覽器上下左右邊緣的距離,如果小于這個(gè)距離就不會(huì)再進(jìn)行調(diào)整寬高
?* ? ? ?dragCallback:拖拽回調(diào)
?*?
?* 使用:
?* ? ? ?在DragBox組件放需要實(shí)現(xiàn)拖拽的div,DragBox組件內(nèi)會(huì)設(shè)置position:absolute(React.cloneElement)
?*/
class DragBox extends Component {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? // 父組件盒子
? ? ? ? this.containerRef = React.createRef();
? ? ? ? // 是否開啟尺寸修改
? ? ? ? this.reSizeAble = false;
? ? ? ? // 鼠標(biāo)按下時(shí)的坐標(biāo),并在修改尺寸時(shí)保存上一個(gè)鼠標(biāo)的位置
? ? ? ? this.clientX, this.clientY;
? ? ? ? // 鼠標(biāo)按下時(shí)的位置,使用n、s、w、e表示
? ? ? ? this.direction = "";
? ? ? ? // 拖拽盒子里瀏覽器上下左右邊緣的距離,如果小于這個(gè)距離就不會(huì)再進(jìn)行調(diào)整寬高
? ? ? ? this.edgeTopDistance = props.edgeDistance[0] || 10;
? ? ? ? this.edgeBottomDistance = props.edgeDistance[1] || 10;
? ? ? ? this.edgeLeftDistance = props.edgeDistance[2] || 10;
? ? ? ? this.edgeRightDistance = props.edgeDistance[3] || 10;
? ? }

? ? componentDidMount(){
? ? ? ? // body監(jiān)聽移動(dòng)事件
? ? ? ? document.body.addEventListener('mousemove', this.move);
? ? ? ? // 鼠標(biāo)松開事件
? ? ? ? document.body.addEventListener('mouseup', this.up);
? ? }

? ? /**
? ? ?* 清除調(diào)整寬高的監(jiān)聽
? ? ?*/
? ? clearEventListener() {
? ? ? ? document.body.removeEventListener('mousemove', this.move);
? ? ? ? document.body.removeEventListener('mouseup', this.up);
? ? }

? ? componentWillUnmount() {
? ? ? ? this.clearEventListener();
? ? }

? ? /**
? ? ?* 鼠標(biāo)松開時(shí)結(jié)束尺寸修改
? ? ?*/
? ? up = () => {
? ? ? ? this.reSizeAble = false;
? ? ? ? this.direction = "";
? ? }

? ? /**
? ? ?* 鼠標(biāo)按下時(shí)開啟尺寸修改
? ? ?* @param {*} e?
? ? ?* @param {String} direction 記錄點(diǎn)擊上下左右哪個(gè)盒子的標(biāo)識(shí)
? ? ?*/
? ? down = (e, direction) => {
? ? ? ? this.direction = direction;
? ? ? ? this.reSizeAble = true;
? ? ? ? this.clientX = e.clientX;
? ? ? ? this.clientY = e.clientY;
? ? }

? ? /**
? ? ?* 鼠標(biāo)按下事件 監(jiān)聽鼠標(biāo)移動(dòng),修改父節(jié)dom位置
? ? ?* @param {DocumentEvent} e 事件參數(shù)
? ? ?* @param {Boolean} changeLeft 是否需要調(diào)整left
? ? ?* @param {Boolean} changeTop 是否需要調(diào)整top
? ? ?* @param {Number} delta 調(diào)整位置的距離差
? ? ?*/
? ? changeLeftAndTop = (event, changeLeft, changeTop, delta) => {
? ? ? ? let ww = document.documentElement.clientWidth;
? ? ? ? let wh = window.innerHeight;

? ? ? ? if (event.clientY < 0 || event.clientX < 0 || event.clientY > wh || event.clientX > ww) {
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? if (changeLeft) {?
? ? ? ? ? ? this.containerRef.current.style.left = Math.max(this.containerRef.current.offsetLeft + delta, this.edgeLeftDistance) + 'px';?
? ? ? ? }
? ? ? ? if (changeTop) {?
? ? ? ? ? ? this.containerRef.current.style.top = Math.max(this.containerRef.current.offsetTop + delta, this.edgeTopDistance) + 'px';?
? ? ? ? }
? ? }

? ? /**
? ? ?* 鼠標(biāo)移動(dòng)事件
? ? ?* @param {*} e?
? ? ?*/
? ? move = (e) => {
? ? ? ? // 當(dāng)開啟尺寸修改時(shí),鼠標(biāo)移動(dòng)會(huì)修改div尺寸
? ? ? ? if (this.reSizeAble) {
? ? ? ? ? ? let finalValue;
? ? ? ? ? ? // 鼠標(biāo)按下的位置在上部,修改高度
? ? ? ? ? ? if (this.direction === "top") {
? ? ? ? ? ? ? ? // 1.距離上邊緣10 不修改
? ? ? ? ? ? ? ? // 2.因?yàn)榘粗敳啃薷母叨葧?huì)修改top、height,所以需要判斷e.clientY是否在offsetTop和this.clientY之間(此時(shí)說(shuō)明處于往上移動(dòng)且鼠標(biāo)位置在盒子上邊緣之下),不應(yīng)該移動(dòng)和調(diào)整盒子寬高
? ? ? ? ? ? ? ? if (e.clientY <= this.edgeTopDistance || (this.containerRef.current.offsetTop < e.clientY && e.clientY ?< this.clientY)){?
? ? ? ? ? ? ? ? ? ? this.clientY = e.clientY;
? ? ? ? ? ? ? ? ? ? return;?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? finalValue = Math.max(this.props.minHeight, this.containerRef.current.offsetHeight + (this.clientY - e.clientY));
? ? ? ? ? ? ? ? // 移動(dòng)的距離,如果移動(dòng)的距離不為0需要調(diào)整高度和top
? ? ? ? ? ? ? ? let delta = this.containerRef.current.offsetHeight - finalValue;
? ? ? ? ? ? ? ? if(delta !== 0){
? ? ? ? ? ? ? ? ? ? this.changeLeftAndTop(e, false, true, delta);?
? ? ? ? ? ? ? ? ? ? this.containerRef.current.style.height = finalValue + "px";
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.clientY = e.clientY;
? ? ? ? ? ? } else if (this.direction === "bottom") {// 鼠標(biāo)按下的位置在底部,修改高度
? ? ? ? ? ? ? ? // 1.距離下邊緣10 不修改
? ? ? ? ? ? ? ? // 2.判斷e.clientY是否處于往下移動(dòng)且鼠標(biāo)位置在盒子下邊緣之上,不應(yīng)該調(diào)整盒子寬高
? ? ? ? ? ? ? ? if (window.innerHeight - e.clientY <= this.edgeBottomDistance || (this.containerRef.current.offsetTop + this.containerRef.current.offsetHeight > e.clientY && e.clientY ?> this.clientY)) {?
? ? ? ? ? ? ? ? ? ? this.clientY = e.clientY;
? ? ? ? ? ? ? ? ? ? return;?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? finalValue = Math.max(this.props.minHeight, this.containerRef.current.offsetHeight + (e.clientY - this.clientY));
? ? ? ? ? ? ? ? this.containerRef.current.style.height = finalValue + "px";
? ? ? ? ? ? ? ? this.clientY = e.clientY;
? ? ? ? ? ? } else if (this.direction === "right") { // 鼠標(biāo)按下的位置在右邊,修改寬度?
? ? ? ? ? ? ? ? // 1.距離右邊緣10 不修改
? ? ? ? ? ? ? ? // 2.判斷e.clientY是否處于往右移動(dòng)且鼠標(biāo)位置在盒子右邊緣之左,不應(yīng)該調(diào)整盒子寬高
? ? ? ? ? ? ? ? if (document.documentElement.clientWidth - e.clientX <= this.edgeRightDistance || (this.containerRef.current.offsetLeft + this.containerRef.current.offsetWidth > e.clientX && e.clientX ?> this.clientX)) {?
? ? ? ? ? ? ? ? ? ? this.clientX = e.clientX;
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 最小為UI設(shè)計(jì)this.props.minWidth,最大為 改邊距離屏幕邊緣-10,其他同此
? ? ? ? ? ? ? ? let value = this.containerRef.current.offsetWidth + (e.clientX - this.clientX);
? ? ? ? ? ? ? ? finalValue = step(value, this.props.minWidth, document.body.clientWidth - this.edgeRightDistance - this.containerRef.current.offsetLeft);
? ? ? ? ? ? ? ? this.containerRef.current.style.width = finalValue + "px";
? ? ? ? ? ? ? ? this.clientX = e.clientX;
? ? ? ? ? ? } else if (this.direction === "left") {// 鼠標(biāo)按下的位置在左邊,修改寬度
? ? ? ? ? ? ? ? // 1.距離左邊緣10 不修改
? ? ? ? ? ? ? ? // 2.因?yàn)榘粗敳啃薷母叨葧?huì)修改left、height,所以需要判斷e.clientY是否在offsetLeft和this.clientY之間(此時(shí)說(shuō)明處于往左移動(dòng)且鼠標(biāo)位置在盒子左邊緣之左),不應(yīng)該移動(dòng)和調(diào)整盒子寬高
? ? ? ? ? ? ? ? if (e.clientX <= this.edgeLeftDistance || (this.containerRef.current.offsetLeft < e.clientX && e.clientX ?< this.clientX)) {?
? ? ? ? ? ? ? ? ? ? this.clientX = e.clientX;
? ? ? ? ? ? ? ? ? ? return;?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? let value = this.containerRef.current.offsetWidth + (this.clientX - e.clientX);
? ? ? ? ? ? ? ? finalValue = step(value, this.props.minWidth, this.containerRef.current.offsetWidth - this.edgeLeftDistance + this.containerRef.current.offsetLeft);
? ? ? ? ? ? ? ? // 移動(dòng)的距離,如果移動(dòng)的距離不為0需要調(diào)整寬度和left
? ? ? ? ? ? ? ? let delta = this.containerRef.current.offsetWidth - finalValue;
? ? ? ? ? ? ? ? if(delta !== 0){
? ? ? ? ? ? ? ? ? ? // 需要修改位置,直接修改寬度只會(huì)向右增加
? ? ? ? ? ? ? ? ? ? this.changeLeftAndTop(e, true, false, delta);?
? ? ? ? ? ? ? ? ? ? this.containerRef.current.style.width = finalValue + "px";
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.clientX = e.clientX;
? ? ? ? ? ? }
? ? ? ? ? ? this.props.dragCallback && this.props.dragCallback(this.direction, finalValue);
? ? ? ? }
? ? }

? ? render() {
? ? ? ? // 四個(gè)紅色盒子 用于鼠標(biāo)移動(dòng)到上面按下進(jìn)行拖動(dòng)
? ? ? ? const children = (
? ? ? ? ? ? <Fragment key={"alphaBar"}>
? ? ? ? ? ? ? ? <div key={1} className={styles.alphaTopBar} onMouseDown={(e) => this.down(e, "top")}></div>
? ? ? ? ? ? ? ? <div key={2} className={styles.alphaBottomBar} onMouseDown={(e) => this.down(e, "bottom")}></div>
? ? ? ? ? ? ? ? <div key={3} className={styles.alphaLeftBar} onMouseDown={(e) => this.down(e, "left")}></div>
? ? ? ? ? ? ? ? <div key={4} className={styles.alphaRightBar} onMouseDown={(e) => this.down(e, "right")}></div>
? ? ? ? ? ? </Fragment>
? ? ? ? );

? ? ? ? // 給傳進(jìn)來(lái)的children進(jìn)行加強(qiáng):添加position:"absolute",添加四個(gè)用于拖動(dòng)的透明盒子
? ? ? ? const childrenProps = this.props.children.props;

? ? ? ? const cloneReactElement = React.cloneElement(
? ? ? ? ? ? this.props.children,
? ? ? ? ? ? {
? ? ? ? ? ? ? ? style: {
? ? ? ? ? ? ? ? ? ? // 復(fù)用原來(lái)的樣式
? ? ? ? ? ? ? ? ? ? ...childrenProps.style,
? ? ? ? ? ? ? ? ? ? // 添加position:"absolute"
? ? ? ? ? ? ? ? ? ? position: "absolute"
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ref: this.containerRef
? ? ? ? ? ? },
? ? ? ? ? ? // 復(fù)用children,添加四個(gè)用于拖動(dòng)的紅色盒子
? ? ? ? ? ? [childrenProps.children, children]
? ? ? ? );

? ? ? ? return (
? ? ? ? ? ? <Fragment>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cloneReactElement
? ? ? ? ? ? ? ? }
? ? ? ? ? ? </Fragment>
? ? ? ? );
? ? }
}

/**
?* 取最大和最小值之間的值
?* @param {*} value?
?* @param {*} min?
?* @param {*} max?
?* @returns?
?*/
function step(value, min, max) {
? ? if (value < min) {
? ? ? ? return min;
? ? } else if (value > max) {
? ? ? ? return max;
? ? } else {
? ? ? ? return value;
? ? }
}

export default DragBox;

### DragBox組件拖動(dòng)條的樣式

.alphaTopBar{
? ? position: absolute;
? ? width: 100%;
? ? height: 8px;
? ? top: -5px;
? ? left: 0;
? ? background-color: red;
? ? cursor: row-resize;
? }
? .alphaBottomBar{
? ? position: absolute;
? ? width: 100%;
? ? height: 8px;
? ? bottom: -5px;
? ? left: 0;
? ? background-color: red;
? ? cursor: row-resize;
? }
? .alphaLeftBar{
? ? position: absolute;
? ? width: 8px;
? ? height: 100%;
? ? top: 0;
? ? left: -5px;
? ? background-color: red;
? ? cursor: col-resize;
? }
? .alphaRightBar{
? ? position: absolute;
? ? width: 8px;
? ? height: 100%;
? ? top: 0;
? ? right: -5px;
? ? background-color: red;
? ? cursor: col-resize;
? }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • react配置antd按需加載的使用

    react配置antd按需加載的使用

    這篇文章主要介紹了react配置antd按需加載的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • JS中使用react-tooltip插件實(shí)現(xiàn)鼠標(biāo)懸浮顯示框

    JS中使用react-tooltip插件實(shí)現(xiàn)鼠標(biāo)懸浮顯示框

    前段時(shí)間遇到的一個(gè)需求,要求鼠標(biāo)懸停顯示使用描述, 用到了react-tooltip插件,今天寫一個(gè)總結(jié),感興趣的朋友跟隨小編一起看看吧
    2019-05-05
  • React Hook父組件如何獲取子組件的數(shù)據(jù)/函數(shù)

    React Hook父組件如何獲取子組件的數(shù)據(jù)/函數(shù)

    這篇文章主要介紹了React Hook父組件如何獲取子組件的數(shù)據(jù)/函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Redux使用方法和基本原理解讀

    Redux使用方法和基本原理解讀

    這篇文章主要介紹了Redux使用方法和基本原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • hooks中useEffect()使用案例詳解

    hooks中useEffect()使用案例詳解

    這篇文章主要介紹了hooks中useEffect()使用總結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • React父子組件間的通信是怎樣進(jìn)行的

    React父子組件間的通信是怎樣進(jìn)行的

    這篇文章主要介紹了React中父子組件通信詳解,在父組件中,為子組件添加屬性數(shù)據(jù),即可實(shí)現(xiàn)父組件向子組件通信,文章通過(guò)圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2023-03-03
  • react系列從零開始_簡(jiǎn)單談?wù)剅eact

    react系列從零開始_簡(jiǎn)單談?wù)剅eact

    下面小編就為大家?guī)?lái)一篇react系列從零開始_簡(jiǎn)單談?wù)剅eact。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息

    react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 如何對(duì)react hooks進(jìn)行單元測(cè)試的方法

    如何對(duì)react hooks進(jìn)行單元測(cè)試的方法

    這篇文章主要介紹了如何對(duì)react hooks進(jìn)行單元測(cè)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Input標(biāo)簽自動(dòng)校驗(yàn)功能去除實(shí)現(xiàn)

    Input標(biāo)簽自動(dòng)校驗(yàn)功能去除實(shí)現(xiàn)

    這篇文章主要為大家介紹了Input標(biāo)簽的自動(dòng)拼寫檢查功能去除實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評(píng)論