drag'n'drop

作者: 寂寞的原子 | 来源:发表于2016-03-31 00:26 被阅读175次

drag'n'drop是HTML5时代装逼必备技能之一,API相关介绍参见强大的MDN,然而新功能总是有很多坑的,让我们来挖一挖。

首先简单描述一下整个流程:

  1. 给想要支持drag的元素(暂且叫做A)加一个draggable="true"的attribute。
  2. 拖拽开始时,A触发dragstart事件,如果这时执行event.preventDefault(),则停止拖拽。
  3. 在拖拽的过程中,拖拽所到之处的元素(把它叫做B)会触发dragenterdragover事件,事件中运行event.preventDefault()才能drop,否则是不会触发drop事件的。
  4. 拖拽结束时,如果可以drop,则在B上会触发drop事件。
  5. 最后在A上触发dragend事件。
dnd.png

这个流程中其实是有很多坑的,下面一点点地挖:

  1. 我们知道,很多时候,HTML元素的属性值与名字相同的时候可以省略值的部分,比如<option value="1" selected="selected">1</option>可以写成<option value="1" selected>1</option>,然而,draggable="true"的值并不是draggable,所以是不能省的!
  2. dragstart事件中,我们通常需要记录一些被拖拽元素的信息,event本身有一个event.dataTransfer.setData(format, data)方法,但是只支持简单的DOMString类型数据,一般来说是不够用的,不如将相关数据另外保存到一个对象中。
    这个时候问题就来了:
    • 不写event.dataTransfer.setData(format, data),Chrome下正常,Firefox不能拖拽。
    • event.dataTransfer.setData('text/plain', ''),Chrome和Firefox正常,IE报错参数异常。
    • 改成event.dataTransfer.setData('text', ''),因为IE只支持formattext,这下Chrome、Firefox、IE都正常了,但是Vivaldi不能拖拽。
    • 最后改成event.dataTransfer.setData('text', 0),因为Vivaldi下data不能为空,终于兼容各大现代浏览器了。
  3. 然后到了dragenterdragover的部分,由于要不断验证数据来判断是否可拖拽,自然就选用了一个dragover事件,当数据合法时event.preventDefault(),然后在除IE以外的浏览器上都正常,而IE依然是不能drop的。最后查MSDN发现,IE需要dragenterdragoverevent.preventDefault()才可以drop。
  4. drop的时候也有个小坑,在Firefox上drop事件如果没有event.preventDefault(),则drop后会发生跳转,然后就没有然后了。
  5. 最后关于dragend有个奇异的小坑,如果你使用的是Windows,那么很有可能你安装了一些诸如QQ电脑管家之类的工具,然后你的浏览器就很有可能被搜狗搜索之类的工具强行插入了,于是一个拖拽结束,立即会打开一个新窗口进行搜索,这时就需要把dragend事件也event.preventDefault()

相关文章

  • drag'n'drop

    drag'n'drop是HTML5时代装逼必备技能之一,API相关介绍参见强大的MDN,然而新功能总是有很多坑的,...

  • Python pandas之删除行、列--Dataframe.d

    drop函数的使用 drop() 删除行和列drop([ ],axis=0,inplace=True)drop([...

  • 数据库学习SQLite(二)

    11.drop 删除命令 drop [table|view|index|trigger] name; drop t...

  • 鲁拜集

    The Wine of Life keeps oozing drop by drop The Leaves of ...

  • #英语笃学#Change The Subject

    1 Let's drop the subject. 让我们换个话题吧。 drop 停止,终止,放弃 Drop ev...

  • Pandas的基本功能(二)

    drop()函数的使用 若要将Series和DataFrame对象中的值删除,可使用drop()函数,drop()...

  • iptables 配置

    iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -...

  • 谷歌官方笔记之 User Interface

    Drag and Drop [[1] developer.android.com ][Drag and Drop]...

  • Drop

    这是很难的事情你要明白,太困难了,在这个世界上活着或者完成某些看似不可能的任务都比这件事来得轻松多了。我没法跟你深...

  • Drop it

    让我们来丢弃数组(arr)的元素,从左边开始,直到回调函数return true就停止。 第二个参数,func,是...

网友评论

本文标题:drag'n'drop

本文链接:https://www.haomeiwen.com/subject/lkjelttx.html