react 日历组件拖拽部分逻辑/元素
目标
我们在上半部分实现了一个可以渲染年月的月视图的日历组件。其中有一个api是cellAppend,可以往日历内容区域写内容。
代码示例如下:
<CalendarcellAppend={(cellData) =>判断在某这个日期展示 && (<div className="cell-append-demo-outer">今天</div>)}/>
好了,我们这里的目标是
- 实现渲染一段日期,比如11号到20号,然后这个日期是可以拖拽的。
- 这段日期的开始位置,可以往左右拉伸,目的让时间段可以增加或者减少
- 同理日期的末尾也是可以拉伸的
- 新建日期:在日历每一天的空白处开始拖拽,拖拽出的一片空白区域可以新建日期。
我们只实现基本的情况,因为这里面会涉及不少的判断,比如多个任务重叠,如何重排序的问题。
渲染时间段
这个很简单,我们渲染的数据必然是一个数组,类似:
const eventList = [{id: 12, // 这段日期的唯一标识idstartTime: "2018-04-4", // 日期起始endTime: "2018-04-15",// 日期结束displayName: "日程1",userId: 1, // 用户id},{id: 15, // 这段日期的唯一标识idstartTime: "2018-04-05",endTime: "2018-04-06",displayName: "日程2",userId: 2, // 用户id},
];
好了,再根据我们上的cellAppend API来看,我们只需要这么渲染
<CalendarcellAppend={(cellData) => {eventList.map(event=>{计算event.startTime和endTime间隔几天(利用dayjs现成的API)然后for循环,遍历这几天 {利用cellData判断是否是for循环的这一天如果是,就渲染出来,渲染的时候需要判断,这是开始,中间还是结束因为UI的展示不一样}})}}/>
好了,我们根据上面的代码就可以渲染各种时间段了,注意,因为日历的高度有限,比如有100个任务在同一天,会超出它的高度,一般我看google日历,react-big-calender,outlook日历等等都是会把这种情况列为 还有 xxx任务,比如还有 23个任务,被折叠起来了。
这个被折叠其实我觉得是没办法的办法,就算折叠了,也会出现一些不好处理的情况,比如我有一段日期,是从1号到4号,在第一天要被折叠,因为排的任务太多了,在2-4天不需要折叠,这种情况不太利于一眼就看出来,因为被折叠了,但是看过主流的日历实现,都解决不好这个问题。所以我们如果做的话,最多也只能做到这个程度了,我来再写一下代码。
<CalendarcellAppend={(cellData) => {eventList.map(event=>{计算event.startTime和endTime间隔几天(利用dayjs现成的API)然后for循环,遍历这几天 {利用cellData判断是否是for循环的这一天如果是,就渲染出来,渲染的时候需要判断,这是开始,中间还是结束+ 这里还要判断这个单元格目前的任务数是否超出了,如果超出,就不需要把这个任务展示出来}})}}/>
新建日期
对了,我们拖拽这部分使用的是react-dnd这个库,我们会利用这个库,监听每一个日期单元格是否是hover状态,比如说啊,我要新建一个任务,从1号到4号,都是空白日期,我鼠标down,然后down的同时move,相当于就是drag事件,从1号拖鼠标到4号,此时拖拽结束,弹出一个框,让我填写新建任务的名称。
这就是新建日期的交互。
所以我们需要监听drag过程中的hover,其实就是dragover事件。
这里需要注意一个逻辑,比如我从1号,拖拽到4号,此时1到4号会有一个UI变化,比如有个浅蓝色的背景表示正在被新建,我就不能简单写为只要是拖拽到的地方就有浅蓝,有可能到了4号,我又拖到3号,这时候就要取消4号的蓝色背景。
所以我们要换一个思路,因为hover的日期我们知道,那么可以计算hover的日期和拖拽起点的日期的距离,也就是间隔多少天,那么我只需要知道正数是往右多少天的背景变为蓝色,负数就是往左多少天变为蓝色。
然后在dragend事件,重新渲染日历组件,我们上面已经写了渲染日期段的逻辑了,这么就新建了一个日期。
当然我们也可以支持点击某个日期,弹框建立新的日期,点击事件我们上一篇文章的代码已经支持了,这个不多说了。
拖拽日期本身
这就需要我们给所有渲染的日期段加上drag事件,如果用react-dnd大概是这样的
// Cell组件
const [ { }, dragRef ] = useDrag({collect: {这个cell的数据,比如id,startTime这些}
})<div ref={dragRef}> 日期 </div>// 日历组件
<CalendarcellAppend={(cellData) => {eventList.map(event=>{return <Cell组件>}})}}/>
好了,当拖拽的时候我们实际上就是改变当前这个日期的startTime和endTime,此时重新渲染我们的日历组件即可,当然需要一个状态,表示正在拖拽日期,dragEnd的时候把这个状态重置。
当然这个也是需要dragover事件去监听的,主要就是靠这个拖拽状态变量告诉dragover,此时是在拖拽日期,不是新建日期。
这段日期的开始位置和结束位置的拖拽拉伸
日期比如3号到4号的一个任务,我从3号那里往左拖,意思是把这个任务延长一点,这也是一个比较常见的用户需求。这个咋做呢。
我们其实要建立一个透明的元素,覆盖在日期段的最前面《诊断证明图片》,这样就可以给这个元素添加拖拽事件了。
拖拽逻辑跟上面差不多,就是需要一个新的状态叫拖拽前面比如叫DRAG_FORWARD,在dragover事件上监听一下。
react 日历组件拖拽部分逻辑/元素相关推荐
- react加水印_多功能React影像组件(拖拽、水印、缩放、切换、旋转)
cxj-react-image 用法如下: yarn add cxj-react-image // npm i cxj-react-image import ImageModal from 'cxj- ...
- react 实现自定义拖拽hook
前沿 最近发现公司的产品好几个模块用到了拖拽功能,之前拖拽组件是通过Html5 drag Api 实现的但体验并不是很好,顺便将原来的拖拽组建稍做修改,写一个自定义hook,方便大家使用拖拽功能. 正 ...
- Vue.Draggable 实现组件拖拽
Vue.Draggable 实现组件拖拽 特性 支持触摸设备 支持拖拽和选择文本 支持智能滚动 支持不同列表之间的拖拽 不以jQuery为基础 和视图模型同步刷新 和vue2的国度动画兼容 支持撤销操 ...
- React Draggable 实现拖拽
React Draggable 实现拖拽 实现步骤 一.安装 react-draggable 二.引入Draggable插件 三.设置一个div,并设置样式,并用Draggable包裹起来 四.设置拖 ...
- vue3 组件拖拽小案例
vue3 实现组件拖拽小案例 一.实现效果 将不同组件拖拽至展示区展示 拖拽前 拖拽后,取消后还原(没有动态演示真抱歉) 二.实现过程 页面基本样式 <template><div c ...
- 【VUE】draggable-实现组件拖拽实例
使用draggable实现组件拖拽 实现步骤 1.导入draggable依赖 npm i -S vuedraggable 2.引入draggable import draggable from &qu ...
- vue拖拽辅助线+改变元素大小组件
vue-dragline 项目根据react-dragline 改写为vue. github地址:https://github.com/BadMooncc/vue-dragline 支持拖拽辅助线,改 ...
- react native 上拖拽元素
1. 给一张效果图 2. 具体代码如下 使用的就是react native里面的PanResponder,具体使用看 官网 这里主要两个知识点Animated 和 panResponder,我在com ...
- 微信小程序 实现最简单的组件拖拽
背景 最近在自主学习微信小程序的开发:对于零基础入门(没有学习过前端)的我,查阅了许多微信小程序拖拽的实现,大部分要么实现起来太复杂了,要么封装组件太复杂了,附带了拖拽之后排序等功能:因此写下这篇个人 ...
最新文章
- linux qml 环境,利用Qml与Golang打造Gui客户端(二)qamel环境安装
- 解决打包软链接打包失败问题
- linux c之通过popen和pclose函数创建管道执行shell 运行命令使用总结
- CString string 转换
- STL源码剖析 空间配置器 查漏补缺
- Matlab画箭头arrow.m
- AD16原理图页设置库路径(1)
- 信号与系统2020参考答案(网络试卷)
- cnpack 菜单顺序
- python+neo4j ,Dota2自走棋,小型知识图谱构建
- Android的性能优化
- 服务器安全(防止被攻击)
- matlab矩形滤波器,MATLAB结合矩形窗设计FIR滤波器
- 谢烟客-----LNP之PHP C 扩展 (Phalcon)
- AD629测量负载电流的电路原理详解——精妙绝伦的电路设计
- 火狐开发版_Firefox普通版和开发版之间有什么区别?
- 机器也能自主区分反义词-同义词 ?!
- bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)
- 【网单服务端】神鬼世界一键安装服务端双镜像优化版网游单机
- C#winform下获取主机ip及hostname