web页面拖放效果的实现

Posted willwillie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web页面拖放效果的实现相关的知识,希望对你有一定的参考价值。

本文主要分析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[url] || url || 'add';
      var iconStyle = _this3.stateIcon.style;
      iconStyle.display = 'block';
      iconStyle.background = 'no-repeat url(' + url + ') center center / 100% auto';
    , 0);
  ,

有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.https://github.com/qgh810/dnd

以上是关于web页面拖放效果的实现的主要内容,如果未能解决你的问题,请参考以下文章

整个页面作为拖放区进行拖放

如何在 php 页面中插入 jqueryUi(显示效果 -> 拖放)

雷林鹏分享:jQuery EasyUI 拖放 - 创建拖放的购物车

论述学习之左右脑

Fabric.js 拖放元素进画布

Web页面中5种超酷的Hover效果