您的位置:首页 > 其它

web页面拖放效果的实现

2018-01-12 11:51 288 查看
本文主要分析dnd.js拖放操作的实现

1.概述:dnd.js主要提供了两个对象给我们使用,一个Drag,一个Drop。可以认为一个是用来拖动的元素,另外一个是用来放下的区域,实际上也确实是这么用的。

2.主要的使用方法:

创建一个拖动元素 new Drag…,和一个拖放区域 new Drop,然后在回调函数里面实现你想要的逻辑,重要的是回调函数。随着拖放动作的进行,这包括一系列的拖放动作,

对于被拖放的元素来说,动作有:

拖动开始、拖动结束,这个时候分别传送一个函数给这一事件(也就是所谓的回调函数),这个函数只能接受一个参数,我们假设这个参数名字是params,params中的内容几乎可以让你进行无限的操作。那么先看看params有哪些,你又可以怎样操作你的拖放过程呢?

data:Drag对象包含的数据,这个必须是数字?

el:指向页面的元素和相关的css属性等

methods:dnd提供的一些操作该元素的方法,这个有很多,比如

showStateIcon(某一个state),state包括warn等。

在dnd.js中的定义是这样的:

/**
* 显示状态icon
* url 可以是图片绝对路径 也可以是 add | error | delete
*/
showStateIcon: function showStateIcon(url) {
var _this3 = this;

setTimeout(function () {
if (_this3.isMobile) return console.warn('showStateIcon仅在pc端口可用 请参考相关说明' + _config.DOCUMENT_ADDR);
url = _iconImages2.default

再举一个例子,比如我们想要被拖动的元素放入到放置区域中。那么应该怎么做?

1、生成一个新的元素

2、删除原来的元素

3、如果你想的化,可以给drop来一个消失(默认的Drag拖动结束的时候效果就是突然的消失,这里不设置也是ok的)的效果

let newNode = params.sourceNode.cloneNode(true)//克隆一个新的sourceNode
params.el.appendChild(newNode)//用dom的方法将这个新元素作为这个drop区域元素的子元素
this.createNewDrap(newNode)//将这个子元素转化为一个Drap对象
let rootNode = document.getElementsByClassName('test-root')[0]
rootNode.removeChild(params.sourceNode)//像上面那样删除原来的元素,当然这里也可以不删除的。


应该怎么将一个普通的克隆的元素转化成一个Drag对象?这其实也跟最外层生成Drag对象的方法是一样的,将这个元素转化为Drag对象,并且传递相应的事件回调函数即可,比如下面这段函数,如果有拖动并且拖动结束的时候就将这个元素删除掉(这里用的也是dom删除的方式)

new Drag(element, {
onDragEnd: function (params) {
console.log(params.el)
var parent = params.el.parentElement
parent.removeChild(params.el)
}
}


从页面的效果来看,这个拖放效果也是很闭环的。把这个拖放区域中的元素拖放到别的空白区域,那么就消失了;拖放到删除区也是消失的;拖放到别的可以存放元素的地方,那就存放到别的地方去了。

destroyDrop:这个目前没有使用到,不知道有什么作用。

I think I drew a circle???(只是排版还有点问题)

拖放的基本使用就说明完了,思考要实现Google日历那样的拖放效果应该怎么做?

1、每一个日期都是一个拖放区域Drop对象

2、单击的时候一个日期可以产生一个Drag,并且弹出event对话框,让你去编辑代办

3.单击并拖动的时候这所有的日期都会产生一个Drag的绘制,从左到右或者从右到左的拖动都是支持的。



是否可以认为一个Drag就是一个单击引起的?经过观测发现其实不是单击,而是在鼠标左键按下的时候,鼠标左键按下又放开后将会弹出一个modal。一个单击按下生成一个drag,然后这个drag默认已经在拖动,最后鼠标停留(又放开)的地方则被认为是真的drop的地方,然后实时计算出鼠标点击的地方和drop区域所经过的所有日期,并且在这所有日期中都画出一个Drag对象的实体表现,然后弹出一个添加event的modal,你就可以编辑这个事件。编辑好后,这个就是页面上的一个Drag元素,然后通过拖动这个元素还可以改变日期,单击这个Drag可以看这个Drag的信息并且修改(这里和drop区域的单击要有所区别,可能需要小心操作,以免引起用户的不满)。

我认为的google日历上最酷炫的技术就是这么实现的,可能存在不准确的地方。

参考文件:

1.[url=https://github.com/qgh810/dnd]https://github.com/qgh810/dnd" target=_blank> || url || 'add';
var iconStyle = _this3.stateIcon.style;
iconStyle.display = 'block';
iconStyle.background = 'no-repeat url(' + url + ') center center / 100% auto';
}, 0);
},[/code]

有add,delete以及warn这些通用图标,效果看起来还是可以的。

hideStateIcon:隐藏状态icon

getStateIconNode:?

removeDragedNode: 移除被拖动的节点

/**
* 移除被拖动的节点
* type 动画类型 不传则无动画直接消失 可选 fade | blost | back
* time 动画持续时长 非必填
*/
removeDragedNode: function removeDragedNode(type, time) {
var _this4 = this;

if (!type) return this.removeMark();
if (!_config.REMOVE_ANIMATION_TYPES[type]) return this.removeMark();
setTimeout(function () {
clearTimeout(_this4.removeMarkTid);
}, 0);
this[_confi


拖动这个动作发生的时候,其实也是复制了一份这个被拖动的元素来进行动画中的动作,

fade的效果是渐渐消失,blost是爆破消失的效果,back的效果是原路返回到了原来的位置。

1.将一个元素拖到垃圾场的实现方式:

在onDrop回调函数中调用:

params.methods.removeDragedNode(‘blost’,3000)

然后将原有的页面元素删除掉,也就是params.sourceNode。

这个时候是能找到params.sourceNode。是不是很好奇在这个情况下的params的内容是什么,为什么跟前面分析的不太一样?(因为每一个事件的参数的内容都不一样)

在onDrop事件发生的时候(Drop区域检测到的事件),这个时候params的值有:

data:对应的drap元素的值

el:对应的drop区域的元素

enter:是否有元素被拖进来

expand:扩展?

methods:和前面论述的methods中的内容是相同的

name:名字

sourceNode:对应的drap元素(拖到这里来的元素。)

得到sourceNode并删除这个页面元素便达到了想要的效果了。

说到这里,先说一下drop区域对应的各种事件和回调函数(因为上面论述的一种情形就已经是关于drop区域的onDrop事件了)。

drop区域的事件比较多,像onDragStart(和被拖动元素的这个方式是一样的),onDragEnd(和被拖动元素的这个方法是一致的),onDrop(一般情况都非常实用的一个方法),onDragEnter(当检测到有被拖动元素进入的时候),onDragLeave(当检测到被拖动元素离开的时候),,onDragOver(当检测到有被拖动元素在区域中的时候)。



再举一个例子,比如我们想要被拖动的元素放入到放置区域中。那么应该怎么做?

1、生成一个新的元素

2、删除原来的元素

3、如果你想的化,可以给drop来一个消失(默认的Drag拖动结束的时候效果就是突然的消失,这里不设置也是ok的)的效果

let newNode = params.sourceNode.cloneNode(true)//克隆一个新的sourceNode
params.el.appendChild(newNode)//用dom的方法将这个新元素作为这个drop区域元素的子元素
this.createNewDrap(newNode)//将这个子元素转化为一个Drap对象
let rootNode = document.getElementsByClassName('test-root')[0]
rootNode.removeChild(params.sourceNode)//像上面那样删除原来的元素,当然这里也可以不删除的。


应该怎么将一个普通的克隆的元素转化成一个Drag对象?这其实也跟最外层生成Drag对象的方法是一样的,将这个元素转化为Drag对象,并且传递相应的事件回调函数即可,比如下面这段函数,如果有拖动并且拖动结束的时候就将这个元素删除掉(这里用的也是dom删除的方式)

new Drag(element, {
onDragEnd: function (params) {
console.log(params.el)
var parent = params.el.parentElement
parent.removeChild(params.el)
}
}


从页面的效果来看,这个拖放效果也是很闭环的。把这个拖放区域中的元素拖放到别的空白区域,那么就消失了;拖放到删除区也是消失的;拖放到别的可以存放元素的地方,那就存放到别的地方去了。

destroyDrop:这个目前没有使用到,不知道有什么作用。

I think I drew a circle???(只是排版还有点问题)

拖放的基本使用就说明完了,思考要实现Google日历那样的拖放效果应该怎么做?

1、每一个日期都是一个拖放区域Drop对象

2、单击的时候一个日期可以产生一个Drag,并且弹出event对话框,让你去编辑代办

3.单击并拖动的时候这所有的日期都会产生一个Drag的绘制,从左到右或者从右到左的拖动都是支持的。



是否可以认为一个Drag就是一个单击引起的?经过观测发现其实不是单击,而是在鼠标左键按下的时候,鼠标左键按下又放开后将会弹出一个modal。一个单击按下生成一个drag,然后这个drag默认已经在拖动,最后鼠标停留(又放开)的地方则被认为是真的drop的地方,然后实时计算出鼠标点击的地方和drop区域所经过的所有日期,并且在这所有日期中都画出一个Drag对象的实体表现,然后弹出一个添加event的modal,你就可以编辑这个事件。编辑好后,这个就是页面上的一个Drag元素,然后通过拖动这个元素还可以改变日期,单击这个Drag可以看这个Drag的信息并且修改(这里和drop区域的单击要有所区别,可能需要小心操作,以免引起用户的不满)。

我认为的google日历上最酷炫的技术就是这么实现的,可能存在不准确的地方。

参考文件:

1.[url=https://github.com/qgh810/dnd]https://github.com/qgh810/dnd
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: