您好,登錄后才能下訂單哦!
這篇文章主要講解了“react如何改變組件大小”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“react如何改變組件大小”吧!
react改變組件大小的方法:1、使用“React.cloneElement”加強包裹組件;2、在包裹的組件設置絕對定位,并在組件內加上四個可調整大小的拖動條;3、點擊拖動條并進行拖動即會改變DragBox的大小。
一、實現流程
1.使用React.cloneElement加強包裹組件,在包裹的組件設置絕對定位,并在組件內加上四個可調整大小的拖動條,在點擊拖動條并進行拖動時會改變DragBox的大小,如下:
2.使用:
<DragBox dragAble={true} minWidth={350} minHeight={184} edgeDistance={[10, 10, 10, 10]} dragCallback={this.dragCallback} >
{/* 使用DragBox拖動組件包裹需要調整大小的盒子 */}
<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";
/**
* 拖拽的公共組件
* 接收參數:
* dragAble:是否開啟拖拽
* minWidth:最小調整寬度
* minHeight:最小調整高度
* edgeDistance:數組,拖拽盒子里瀏覽器上下左右邊緣的距離,如果小于這個距離就不會再進行調整寬高
* dragCallback:拖拽回調
*
* 使用:
* 在DragBox組件放需要實現拖拽的div,DragBox組件內會設置position:absolute(React.cloneElement)
*/
class DragBox extends Component {
constructor(props) {
super(props);
// 父組件盒子
this.containerRef = React.createRef();
// 是否開啟尺寸修改
this.reSizeAble = false;
// 鼠標按下時的坐標,并在修改尺寸時保存上一個鼠標的位置
this.clientX, this.clientY;
// 鼠標按下時的位置,使用n、s、w、e表示
this.direction = "";
// 拖拽盒子里瀏覽器上下左右邊緣的距離,如果小于這個距離就不會再進行調整寬高
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監聽移動事件
document.body.addEventListener('mousemove', this.move);
// 鼠標松開事件
document.body.addEventListener('mouseup', this.up);
}
/**
* 清除調整寬高的監聽
*/
clearEventListener() {
document.body.removeEventListener('mousemove', this.move);
document.body.removeEventListener('mouseup', this.up);
}
componentWillUnmount() {
this.clearEventListener();
}
/**
* 鼠標松開時結束尺寸修改
*/
up = () => {
this.reSizeAble = false;
this.direction = "";
}
/**
* 鼠標按下時開啟尺寸修改
* @param {*} e
* @param {String} direction 記錄點擊上下左右哪個盒子的標識
*/
down = (e, direction) => {
this.direction = direction;
this.reSizeAble = true;
this.clientX = e.clientX;
this.clientY = e.clientY;
}
/**
* 鼠標按下事件 監聽鼠標移動,修改父節dom位置
* @param {DocumentEvent} e 事件參數
* @param {Boolean} changeLeft 是否需要調整left
* @param {Boolean} changeTop 是否需要調整top
* @param {Number} delta 調整位置的距離差
*/
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';
}
}
/**
* 鼠標移動事件
* @param {*} e
*/
move = (e) => {
// 當開啟尺寸修改時,鼠標移動會修改div尺寸
if (this.reSizeAble) {
let finalValue;
// 鼠標按下的位置在上部,修改高度
if (this.direction === "top") {
// 1.距離上邊緣10 不修改
// 2.因為按著頂部修改高度會修改top、height,所以需要判斷e.clientY是否在offsetTop和this.clientY之間(此時說明處于往上移動且鼠標位置在盒子上邊緣之下),不應該移動和調整盒子寬高
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));
// 移動的距離,如果移動的距離不為0需要調整高度和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") {// 鼠標按下的位置在底部,修改高度
// 1.距離下邊緣10 不修改
// 2.判斷e.clientY是否處于往下移動且鼠標位置在盒子下邊緣之上,不應該調整盒子寬高
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") { // 鼠標按下的位置在右邊,修改寬度
// 1.距離右邊緣10 不修改
// 2.判斷e.clientY是否處于往右移動且鼠標位置在盒子右邊緣之左,不應該調整盒子寬高
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設計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") {// 鼠標按下的位置在左邊,修改寬度
// 1.距離左邊緣10 不修改
// 2.因為按著頂部修改高度會修改left、height,所以需要判斷e.clientY是否在offsetLeft和this.clientY之間(此時說明處于往左移動且鼠標位置在盒子左邊緣之左),不應該移動和調整盒子寬高
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);
// 移動的距離,如果移動的距離不為0需要調整寬度和left
let delta = this.containerRef.current.offsetWidth - finalValue;
if(delta !== 0){
// 需要修改位置,直接修改寬度只會向右增加
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() {
// 四個紅色盒子 用于鼠標移動到上面按下進行拖動
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>
);
// 給傳進來的children進行加強:添加position:"absolute",添加四個用于拖動的透明盒子
const childrenProps = this.props.children.props;
const cloneReactElement = React.cloneElement(
this.props.children,
{
style: {
// 復用原來的樣式
...childrenProps.style,
// 添加position:"absolute"
position: "absolute"
},
ref: this.containerRef
},
// 復用children,添加四個用于拖動的紅色盒子
[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組件拖動條的樣式
.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;
}
感謝各位的閱讀,以上就是“react如何改變組件大小”的內容了,經過本文的學習后,相信大家對react如何改變組件大小這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。