目标

我们在上半部分实现了一个可以渲染年月的月视图的日历组件。其中有一个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 日历组件拖拽部分逻辑/元素相关推荐

  1. react加水印_多功能React影像组件(拖拽、水印、缩放、切换、旋转)

    cxj-react-image 用法如下: yarn add cxj-react-image // npm i cxj-react-image import ImageModal from 'cxj- ...

  2. react 实现自定义拖拽hook

    前沿 最近发现公司的产品好几个模块用到了拖拽功能,之前拖拽组件是通过Html5 drag Api 实现的但体验并不是很好,顺便将原来的拖拽组建稍做修改,写一个自定义hook,方便大家使用拖拽功能. 正 ...

  3. Vue.Draggable 实现组件拖拽

    Vue.Draggable 实现组件拖拽 特性 支持触摸设备 支持拖拽和选择文本 支持智能滚动 支持不同列表之间的拖拽 不以jQuery为基础 和视图模型同步刷新 和vue2的国度动画兼容 支持撤销操 ...

  4. React Draggable 实现拖拽

    React Draggable 实现拖拽 实现步骤 一.安装 react-draggable 二.引入Draggable插件 三.设置一个div,并设置样式,并用Draggable包裹起来 四.设置拖 ...

  5. vue3 组件拖拽小案例

    vue3 实现组件拖拽小案例 一.实现效果 将不同组件拖拽至展示区展示 拖拽前 拖拽后,取消后还原(没有动态演示真抱歉) 二.实现过程 页面基本样式 <template><div c ...

  6. 【VUE】draggable-实现组件拖拽实例

    使用draggable实现组件拖拽 实现步骤 1.导入draggable依赖 npm i -S vuedraggable 2.引入draggable import draggable from &qu ...

  7. vue拖拽辅助线+改变元素大小组件

    vue-dragline 项目根据react-dragline 改写为vue. github地址:https://github.com/BadMooncc/vue-dragline 支持拖拽辅助线,改 ...

  8. react native 上拖拽元素

    1. 给一张效果图 2. 具体代码如下 使用的就是react native里面的PanResponder,具体使用看 官网 这里主要两个知识点Animated 和 panResponder,我在com ...

  9. 微信小程序 实现最简单的组件拖拽

    背景 最近在自主学习微信小程序的开发:对于零基础入门(没有学习过前端)的我,查阅了许多微信小程序拖拽的实现,大部分要么实现起来太复杂了,要么封装组件太复杂了,附带了拖拽之后排序等功能:因此写下这篇个人 ...

最新文章

  1. linux qml 环境,利用Qml与Golang打造Gui客户端(二)qamel环境安装
  2. 解决打包软链接打包失败问题
  3. linux c之通过popen和pclose函数创建管道执行shell 运行命令使用总结
  4. CString string 转换
  5. STL源码剖析 空间配置器 查漏补缺
  6. Matlab画箭头arrow.m
  7. AD16原理图页设置库路径(1)
  8. 信号与系统2020参考答案(网络试卷)
  9. cnpack 菜单顺序
  10. python+neo4j ,Dota2自走棋,小型知识图谱构建
  11. Android的性能优化
  12. 服务器安全(防止被攻击)
  13. matlab矩形滤波器,MATLAB结合矩形窗设计FIR滤波器
  14. 谢烟客-----LNP之PHP C 扩展 (Phalcon)
  15. AD629测量负载电流的电路原理详解——精妙绝伦的电路设计
  16. 火狐开发版_Firefox普通版和开发版之间有什么区别?
  17. 机器也能自主区分反义词-同义词 ?!
  18. bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)
  19. 【网单服务端】神鬼世界一键安装服务端双镜像优化版网游单机
  20. C#winform下获取主机ip及hostname

热门文章

  1. JS/Jquery遍历JSON对象、JSON数组、JSON数组字符串、JSON对象字符串
  2. 泛微 e-office v9.0任意文件上传漏洞(CNVD-2021-49104)
  3. 3A限流开关芯片,2.4A限流芯片
  4. 关于日期和时间的解析
  5. 象의 圖像-象과 數의 圖像과 時運
  6. Angular4简介
  7. daemon(守护进程)
  8. html 绘制体温单,使用zrender.js绘制体温单效果
  9. 惠普服务器找不到阵列,HP服务器RAID设置方法介绍
  10. Java自动生成数据库设计文档(Word)