1. Введение
Блогер недавно столкнулся с таким небольшим требованием в процессе разработки:
Левая часть панели поддерживает функцию перетаскивания, которая позволяет пользователям видеть полный каталог.
Советы: часть диспетчера ресурсов редактора vscode также поддерживает функцию перетаскивания, которая аналогична функции перетаскивания границы.
2. Подумайте
Существует два способа реализации перетаскивания:
(1) С помощью новых API-интерфейсов, связанных с перетаскиванием, в html5.
Главная идея:
Установите элементы для перетаскивания (draggable
) =>ondragstart
Установите тип и значение данных перетаскивания =>ondragover
Расположено там, где размещать данные =>ondrop
Перетащите элементы в пункт назначения
Среди них можно позаимствовать расчет дистанции перемещения мыши.event.clientX
Получать.
(2) С помощью плагинов для достижения
Блогер отправился на github, чтобы найти хороший плагин, который можно перетаскивать,нпм ссылка.
Советы:
react-draggable
перетаскиваниеCSS
серединаtransform: translate(x, y)
для достижения движения целевого элемента.
3. Реагировать на перетаскивание
(1) Установкаreact-draggable
$ npm install react-draggable --save
(2) Цитата
import Draggable from 'react-draggable';
(3) Общий реквизит
allowAnyClick: boolean // 默认false,设为true非左键可实现点击拖拽
axis: string // 'x':x轴方向拖拽、'y':y轴方向拖拽、'none':禁止拖拽
bounds: { left: number, top: number, right: number, bottom: number } | string
// 限定移动的边界,接受值:
//(1)'parent':在移动元素的offsetParent范围内
//(2)一个选择器,在指定的Dom节点内
//(3){ left: number, top: number, right: number, bottom: number }对象,限定每个方向可以移动的距离
cancel:制定给一个选择器组织drag初始化,例如'.body'
defaultClassName:string // 拖拽ui类名,默认'react-draggable'
drfaultClassNameDragging:string // 正在拖拽ui类名,默认'eact-draggable-dragging'
defaultClassNameDragged:string //拖拽后的类名,默认'react-draggable-dragged'
defaultPosition:{ x: number, y: number } // 起始x和y的位置
disabled:boolean // true禁止拖拽任何元素
grid:[number, number] // 正在拖拽的网格范围
handle:string // 初始拖拽的的选择器'.handle'
offsetParent:HTMLElement // 拖拽的offsetParent
onMouseDown: (e: MouseEvent) => void // 鼠标按下的回调
onStart: DraggableEventHandler // 开始拖拽的回调
onDrag:DraggableEventHandler // 拖拽时的回调
onStop:DraggableEventHandler // 拖拽结束的回调
position: {x: number, y: number} // 控制元素的位置
positionOffset: {x: number | string, y: number | string} // 相对于起始位置的偏移
scale:number // 定义拖拽元素的缩放
(4) Пример
class App extends React.Component {
eventLogger = (e: MouseEvent, data: Object) => {
console.log('Event: ', e);
console.log('Data: ', data);
};
render() {
return (
<Draggable
axis="x"
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
grid={[25, 25]}
scale={1}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<div>
<div className="handle">Drag from here</div>
<div>This readme is really dragging on...</div>
</div>
</Draggable>
);
}
}
4. Осознайте
4.1 Идеи
(1) Лучше всего использовать левое и правое полеflex
Макет, левое поле инициалwidth
установить какNpx
правильная ширина коробкиcalc(100% - Npx)
.
(2) Установите границу перетаскивания (перетаскивание) внутри левого поля шириной5px
,background-color
установить какtransparent
,cursor
установить какcol-resiz
, как показано в зеленой части рисунка ниже:
background-color
Для видимого цвета обновите левое и правое поля одновременно.width
Вот и все, перетащите, чтобы закончить перетаскиваниеbackground-color
сбросить наtransparent
.
4.2 Реализация кода
упоминается в кодеstyled-components
, это набор, написанный для Reactcss in js
Каркас, говоря простым языком,js
китайский языкcss
, компонент может быть легко реализованcss
модульный, похожий наvue
компонентstyle
Добавленscoped
Атрибуты.
Хотеть учитьсяstyled-components
друзья могут просматриватьСвязь.
import React, { Component } from 'react';
import Draggable from 'react-draggable';
import styled from 'styled-components';
// 容器
const Container = styled.div`
display: flex;
justify-content: flex-start;
`;
// 左边内容部分
const LeftContent = styled.div`
position: relative;
width: ${props => props.width}px;
height: 100vh;
padding: 20px;
background-color: #E6E6FA;
overflow: hidden;
flex-grow:1;
`;
// 拖拽部分
const DraggableBox = styled.div`
position: absolute;
left: ${props => props.left}px;
top: 0;
width: 5px;
height: 100vh;
background-color: ${props => props.background};
cursor: col-resize;
z-index: 1000;
`;
// 右边内容部分
const RightContent = styled.div`
width: calc(100% - ${props => props.leftBoxWidth}px);
height: 100vh;
padding: 20px;
background-color: #FFF;
flex-grow:1;
z-index: 100;
`;
const Li = styled.li`
white-space: nowrap;
`;
class DraggableExp extends Component {
state = {
initialLeftBoxWidth: 150, // 左边区块初始宽度
leftBoxWidth: 150, // 左边区块初始宽度
leftBoxMinWidth: 100, // 左边区块最小宽度
leftBoxMaxWidth: 300, // 左边区块最大宽度
dragBoxBackground: 'transparent' // 拖拽盒子的背景色
}
// 拖动时设置拖动box背景色,同时更新左右box的宽度
onDrag = (ev, ui) => {
const { initialLeftBoxWidth } = this.state;
const newLeftBoxWidth = ui.x + initialLeftBoxWidth;
this.setState({
leftBoxWidth: newLeftBoxWidth,
dragBoxBackground: '#FFB6C1'
});
};
// 拖拽结束,重置drag-box的背景色
onDragStop = () => {
this.setState({
dragBoxBackground: 'transparent'
});
};
render() {
const { initialLeftBoxWidth,
leftBoxWidth,
leftBoxMinWidth,
leftBoxMaxWidth,
dragBoxBackground } = this.state;
return (
<Container>
<LeftContent width={leftBoxWidth}>
<h3 style={{paddingLeft: 20}}>目录</h3>
<ul>
<Li>目录1</Li>
<Li>目录2</Li>
<Li>目录3</Li>
<Li>这是个非常长非常长非常长的目录</Li>
</ul>
<Draggable
axis="x"
defaultPosition={{ x: 0, y: 0 }}
bounds={{ left: leftBoxMinWidth - initialLeftBoxWidth, right: leftBoxMaxWidth - initialLeftBoxWidth }}
onDrag={this.onDrag}
onStop={this.onDragStop}>
<DraggableBox
left={initialLeftBoxWidth - 5}
background={dragBoxBackground} />
</Draggable>
</LeftContent>
<RightContent leftBoxWidth={leftBoxWidth}>
<h3>这里是内容块</h3>
</RightContent>
</Container>
)
}
}
export default DraggableExp;
4.3 Осознайте эффект
начальное состояние:
Выше приведена небольшая функция, которую блоггеры используют react-draggable для реализации перетаскивания границ. Заинтересованные друзья могут попробовать ее сами.
(Друзья, которые считают, что это хорошо, могут поставить лайк статье, кодировать слова непросто, большое спасибо ^_^)