Javascript 尝试在React中创建可调整大小的列时遇到问题
我试图在react中创建可调整大小的列,我做得很好,我可以在只使用几列的情况下使其工作,但当我尝试嵌套它们时,情况开始变得很糟糕,例如,当我拖动列以调整其大小时,它无法正常工作,就像如果我移动得不太慢,它会停止听我的鼠标移动一样,而它不会发生在非嵌套列上。这听起来很离谱,但如果你看到代码,它会变得更清晰。我想不出这个问题:( 列文件Javascript 尝试在React中创建可调整大小的列时遇到问题,javascript,reactjs,web,frontend,responsive,Javascript,Reactjs,Web,Frontend,Responsive,我试图在react中创建可调整大小的列,我做得很好,我可以在只使用几列的情况下使其工作,但当我尝试嵌套它们时,情况开始变得很糟糕,例如,当我拖动列以调整其大小时,它无法正常工作,就像如果我移动得不太慢,它会停止听我的鼠标移动一样,而它不会发生在非嵌套列上。这听起来很离谱,但如果你看到代码,它会变得更清晰。我想不出这个问题:( 列文件 import React, { useState, useEffect } from 'react'; function Columns( props ) {
import React, { useState, useEffect } from 'react';
function Columns( props ) {
const [ isResizing, setIsResizing ] = useState( false );
const [ target, setTarget ] = useState();
const [ parentClientRect, setParentClientRect ] = useState();
const [ columnsPercentages, setColumnsPercentages ] = useState([{}]);
const count = props.children.length;
const minWidth = 5;
useEffect(()=>{
const initialColumnPercentage = 100 / count;
const initialColumnsPercentageArray = [];
for( let i = 0; i < count; i++ ){
initialColumnsPercentageArray.push( initialColumnPercentage );
}
setColumnsPercentages([...initialColumnsPercentageArray]);
},[]);// eslint-disable-line react-hooks/exhaustive-deps
const handleMouseMove = ( e ) =>{
if ( !isResizing ) return;
console.log( target );
let newPerc = ((( e.pageX - parentClientRect.x ) * 100 ) / parentClientRect.width ) + 1;
if ( target !== 0 ){
let percentageToSubtract = 0;
for( let i = 0; i < target; i++ ){
percentageToSubtract = percentageToSubtract + columnsPercentages[i];
}
newPerc = newPerc - percentageToSubtract;
}
if ( newPerc > 100 - ( count - 1 ) * minWidth ){
newPerc = 100 - ( count - 1 ) * minWidth;
}
let newPercentagesArray = columnsPercentages;
newPercentagesArray.splice( target, 1, newPerc );
let totalPercentage = newPercentagesArray.reduce(( a, b ) => a + b );
if ( totalPercentage !== 100 ){
let nextColumnPerc = 100 - newPercentagesArray[target] - ( totalPercentage - ( newPercentagesArray[target] + newPercentagesArray[target + 1]));
if ( nextColumnPerc < minWidth ){
nextColumnPerc = minWidth;
}
newPercentagesArray.splice( target + 1, 1, nextColumnPerc );
}
setColumnsPercentages([...newPercentagesArray]);
};
const handleMouseUp = ( e ) =>{
setIsResizing( false );
setTarget( null );
setParentClientRect( null );
};
const handleMouseDown = ( e, key ) =>{
e.stopPropagation();
setTarget( key );
setParentClientRect( e.target.parentElement.getBoundingClientRect());
setIsResizing( true );
};
return (
<main className="columns" onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} >
{
React.Children.map( props.children, (( x, index )=> React.cloneElement( x, {
key: index,
onMouseDown: ( e ) => handleMouseDown( e, index ),
initialWidth: 100 / count,
maxWidth: 100 - ( count - 1 ) * minWidth,
columnsPercentages,
index
})))
}
</main>
);
}
export default Columns;
import React, { useState, useEffect } from 'react';
function Column( props ) {
const { index, className = '', maxWidth, minWidth = '5%', initialWidth, columnsPercentages, onMouseDown } = props;
const [ width, setWidth ] = useState( initialWidth );
useEffect(()=>{
console.log( columnsPercentages );
if ( columnsPercentages[index] != null ){
if ( columnsPercentages[index] !== width ){
setWidth( columnsPercentages[index]);
}
}
},[columnsPercentages]);// eslint-disable-line react-hooks/exhaustive-deps
return (
<section className={`column ${className}`} style={{ maxWidth:`${maxWidth}%`, minWidth, width:`${width}%` }}
onMouseDown={onMouseDown} >
{props.children}
</section>
);
}
export default Column;
import React,{useState,useffect}来自“React”;
功能栏(道具){
const[IsResising,setIsResising]=useState(false);
const[target,setTarget]=useState();
const[parentClientRect,setParentClientRect]=useState();
const[columnsPercentages,setColumnsPercentages]=useState([{}]);
const count=props.children.length;
常数最小宽度=5;
useffect(()=>{
常量initialColumnPercentage=100/计数;
const initialColumnsPercentageArray=[];
for(设i=0;i{
如果(!IsResising)返回;
控制台日志(目标);
设newPerc=((e.pageX-parentClientRect.x)*100)/parentClientRect.width)+1;
如果(目标!==0){
设percentageToSubtract=0;
for(设i=0;i100-(计数-1)*最小宽度){
newPerc=100-(计数-1)*最小宽度;
}
让newPercentagesArray=columnsPercentages;
newPercentagesArray.拼接(目标,1,newPerc);
让totalPercentage=newPercentagesArray.reduce((a,b)=>a+b);
如果(总百分比!==100){
设nextColumnPerc=100-newPercentagesArray[target](totalPercentage-(newPercentagesArray[target]+newPercentagesArray[target+1]);
if(nextColumnPerc<最小宽度){
nextColumnPerc=最小宽度;
}
newPercentagesArray.splice(目标+1,1,下一列PERC);
}
setColumnsPercentages([…newPercentagesArray]);
};
常数handleMouseUp=(e)=>{
SetIsResising(假);
setTarget(空);
setParentClientRect(空);
};
常量handleMouseDown=(e,键)=>{
e、 停止传播();
设置目标(键);
setParentClientRect(e.target.parentElement.getBoundingClientRect());
SetIsResising(真);
};
返回(
{
React.Children.map(props.Children,((x,index)=>React.cloneElement(x{
关键词:索引,,
onMouseDown:(e)=>handleMouseDown(e,索引),
初始宽度:100/计数,
最大宽度:100-(计数-1)*最小宽度,
柱状结构,
指数
})))
}
);
}
导出默认列;
列文件
import React, { useState, useEffect } from 'react';
function Columns( props ) {
const [ isResizing, setIsResizing ] = useState( false );
const [ target, setTarget ] = useState();
const [ parentClientRect, setParentClientRect ] = useState();
const [ columnsPercentages, setColumnsPercentages ] = useState([{}]);
const count = props.children.length;
const minWidth = 5;
useEffect(()=>{
const initialColumnPercentage = 100 / count;
const initialColumnsPercentageArray = [];
for( let i = 0; i < count; i++ ){
initialColumnsPercentageArray.push( initialColumnPercentage );
}
setColumnsPercentages([...initialColumnsPercentageArray]);
},[]);// eslint-disable-line react-hooks/exhaustive-deps
const handleMouseMove = ( e ) =>{
if ( !isResizing ) return;
console.log( target );
let newPerc = ((( e.pageX - parentClientRect.x ) * 100 ) / parentClientRect.width ) + 1;
if ( target !== 0 ){
let percentageToSubtract = 0;
for( let i = 0; i < target; i++ ){
percentageToSubtract = percentageToSubtract + columnsPercentages[i];
}
newPerc = newPerc - percentageToSubtract;
}
if ( newPerc > 100 - ( count - 1 ) * minWidth ){
newPerc = 100 - ( count - 1 ) * minWidth;
}
let newPercentagesArray = columnsPercentages;
newPercentagesArray.splice( target, 1, newPerc );
let totalPercentage = newPercentagesArray.reduce(( a, b ) => a + b );
if ( totalPercentage !== 100 ){
let nextColumnPerc = 100 - newPercentagesArray[target] - ( totalPercentage - ( newPercentagesArray[target] + newPercentagesArray[target + 1]));
if ( nextColumnPerc < minWidth ){
nextColumnPerc = minWidth;
}
newPercentagesArray.splice( target + 1, 1, nextColumnPerc );
}
setColumnsPercentages([...newPercentagesArray]);
};
const handleMouseUp = ( e ) =>{
setIsResizing( false );
setTarget( null );
setParentClientRect( null );
};
const handleMouseDown = ( e, key ) =>{
e.stopPropagation();
setTarget( key );
setParentClientRect( e.target.parentElement.getBoundingClientRect());
setIsResizing( true );
};
return (
<main className="columns" onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} >
{
React.Children.map( props.children, (( x, index )=> React.cloneElement( x, {
key: index,
onMouseDown: ( e ) => handleMouseDown( e, index ),
initialWidth: 100 / count,
maxWidth: 100 - ( count - 1 ) * minWidth,
columnsPercentages,
index
})))
}
</main>
);
}
export default Columns;
import React, { useState, useEffect } from 'react';
function Column( props ) {
const { index, className = '', maxWidth, minWidth = '5%', initialWidth, columnsPercentages, onMouseDown } = props;
const [ width, setWidth ] = useState( initialWidth );
useEffect(()=>{
console.log( columnsPercentages );
if ( columnsPercentages[index] != null ){
if ( columnsPercentages[index] !== width ){
setWidth( columnsPercentages[index]);
}
}
},[columnsPercentages]);// eslint-disable-line react-hooks/exhaustive-deps
return (
<section className={`column ${className}`} style={{ maxWidth:`${maxWidth}%`, minWidth, width:`${width}%` }}
onMouseDown={onMouseDown} >
{props.children}
</section>
);
}
export default Column;
import React,{useState,useffect}来自“React”;
功能栏(道具){
const{index,className='',maxWidth,minWidth='5%',initialWidth,columnsPercentages,onMouseDown}=props;
const[width,setWidth]=useState(initialWidth);
useffect(()=>{
console.log(columnsPercentages);
if(columnsPercentages[index]!=null){
if(columnsPercentages[索引]!==宽度){
setWidth(columnsPercentages[索引]);
}
}
},[columnsPercentages];//eslint禁用行反应挂钩/穷举deps
返回(
{props.children}
);
}
导出默认列;
实施
import React, { useState } from 'react';
import Columns from '../common/Columns.jsx';
import Column from '../common/Column.jsx';
function ImplementationColumns( props ){
return (
<>
<Columns>
<Column>
<p style={{ textAlign: 'center', lineHeight: '100px' }}>section 1</p>
<Columns>
<Column>
<p style={{ textAlign: 'center', lineHeight: '100px' }}>nested 1</p>
</Column>
<Column>
<p style={{ textAlign: 'center', lineHeight: '100px' }}>nested 2</p>
</Column>
<Column>
<p style={{ textAlign: 'center', lineHeight: '100px' }}>nested 3</p>
</Column>
</Columns>
</Column>
<Column>
<p style={{ textAlign: 'center', lineHeight: '100px' }}>section 2</p>
</Column>
</Columns>
</>
);
}
export default ImplementationColumns;
import React,{useState}来自“React”;
从“../common/Columns.jsx”导入列;
从“../common/Column.jsx”导入列;
功能实现列(道具){
返回(
第1节
嵌套1
nested 2
嵌套3
第2节
);
}
导出默认实现列;