资讯专栏INFORMATION COLUMN

拖动中的味道

468122151 / 2572人阅读

摘要:内容不可被拖动。指定一个元素拖动发生时显示在光标下方,三个参数分别是要显示的元素和光标在显示元素中的坐标。返回被拖放文件的对象。返回事件中传递的数据类型的类似数组的集合。

拖~

在js里面关于拖这个概念是完全没有的(except h5). 以前只能造一大堆的轮子,比如使用mousedown + mousemove + mouseup. 这3个事件结合起来实现复杂的UI操作。 现在,h5出了一个拖拽系列的事件,可以部分省去我们的劳动。
现在基本的理一下吧。

H5之拖拽系列

1.针对被拖动元素的事件有:

dragstart ,drag, dragend.

触发顺序为: dragstart(一次)--drag(移动时触发)--dragend(一次,拖拽结束触发)

2.针对放置目标上的事件有:

dragenter,dragover,dragleave||drop.

字面上其实就可以理解
当有元素被拖过来时,首先会触发dragenter事件,然后触发dragover事件,如果你的没有将拖动元素放下,而是移开则会触发dragleave事件。
否则会触发drop事件.

上面只是理论,如果你实践起来,你会发现。(MD~) 这根本不能用啊~ 所以说,实践才是检验真理的唯一标准。
其实拖拽里面还有一些坑

拖拽的坑

首先拖放元素上面需要设置为draggable 为 true. (默认为false) 然后才可以拖动了。

属性值 说明
true 内容可被拖动。
false 内容不可被拖动。
auto 内容执行默认的浏览器行为(图像、链接和被选中的文本可被拖动,其他元素不能)

但是上面的设置只能在IE10+以上运行。 如果想向下兼容IE9的话(IE8不考虑). 则需要在元素上绑定mouseDown事件,通过调用dragDrop()方法来进行兼容.

subject.addEventListener("mousedown",function(e){
    subject.dragDrop();
},false);

哎~ 怎么说嘞, 其实这个拖拽是IE发明的,h5把他收录了并且做了些微创新(其实改动蛮大的). 但是h5新定义的一些属性在IE的低版本中不能实现(cao~ 都怪IE一开始没有提示更新的机制)
在拖放过程中,会产生一个dataTransfer的对象. 最基本的方法就两个一个是.setData()和.getData(); 这是所有浏览器都兼容的。

方法 说明
clearData(format) 清除以特定格式保存的数据 。
getData(format) 从 dataTransfer 对象中读取指定类型的值,参数是 MIME 类型。
setData(format, data) 为 dataTransfer 对象指定特定格式的数据,这些数据只能在 ondrop 处理程序中读取。
setDragImage(element, x, y) 指定一个元素拖动发生时显示在光标下方,三个参数分别是要显示的 HTML元素和光标在显示元素中的x、y坐标。
addElement(element) 如果想要让某个元素跟随被拖拽元素一同被拖拽,可使用该方法。由于只有FF实现了这个方法,我这里就不赘述了

其实上面真正能投入生产的只有getData和setData。因为我们的目的兼容是IE8+。 所以其他的方法,哎~ 不过说都说了也得介绍一下。

关于setData,IE只定义了“text”和“URL”两种有效的数据类型. 但是H5 将类型扩展为所有的MIME。 然而这也造成了兼容性的麻烦。 聪明的H5 为了 兼容IE(因为这个对象是IE发明的). 他在解析的时候会默认将“text”和“URL” 转为“text/plain”和“text/uri-list”.

这里再次阐明一下使用setData和getData事件的时机.

setData(); 只能在dragstart事件中使用
getData(); 只能在drop事件中使用。

其实也是废话了。如果要求对拖拽要求不高的话,只需要对拖拽设置一个dragstart事件就够了.
对于setDragImage这个方法,可以说一下。默认的话就是使用被拖拽元素本身,但是使用这个方法就可以自定义被拖放元素是HTML元素中的哪一个(也并没有什么卵用).
这是一个非常基本的例子:
拖拽实例

//html很简单
 
//看一下js代码(这里是es6的写法) let subject = document.querySelector(".subject"), container = document.querySelector(".container"); subject.addEventListener("dragstart",function(e){ let data = e.dataTransfer; data.setData("text","123"); data.addElement(container); },false); container.addEventListener("dragover",function(e){ e.preventDefault(); },false); container.addEventListener("dragenter",function(e){ e.preventDefault(); },false); container.addEventListener("drop",function(e){ let data = e.dataTransfer.getData("text"); this.innerHTML = data; console.dir(data); }); window.ondrop = function(e){ e.preventDefault(); }

如果你的文件是从外面引入的,浏览器默认会自动新打开一个网页来。 所以这里需要禁止掉浏览器的默认行为.
使用 e.preventDefault();
由于目标元素默认不会开启容器的功能,这里你需要使用

container.addEventListener("dragover",function(e){
    e.preventDefault();
},false);
container.addEventListener("dragenter",function(e){
    e.preventDefault();
},false);  

这两段代码开启容器效果(记住两个都必须有).
此外dataTransfer 对象上还有几个属性.

Property Description
dropEffect 获取或设置被拖动元素能够执行哪中放置行为,不同的行为显示相应的光标。
effectAllowed 表示允许拖动元素的哪种 dropEffect。
files 返回被拖放文件的FileList对象。
types 返回ondragstart事件中传递的数据类型的类似数组的集合。

来看一看里面有哪些设置值吧

dropEffect的属性值分别有

(1) none:不能放置拖动元素(除文本框以外所有元素的默认值);

(2) move:应该把元素移动到放置目标;

(3) copy:应该把拖动元素复制到放置目标;

(4) link:应该在放置目标上打开拖动元素(拖动元素必须是有 URL 的链接)。

而且现在可以使用dragzone来代替上面两个属性的设置.

effectAllowed的属性值分别有:

(1) uninitialized:被拖动元素没有设置放置行为;

(2) none:被拖动元素不允许有任何行为;

(3) copy:只允许 copy 值的 dropEffect;

(4) move:只允许 move 值的 dropEffect;

(5) copeLink:copy 和 link 值的 dropEffect;

(6) copeMove:copy 和 move 值的 dropEffect;

(7) linkMove:link 和 move 值的 dropEffect;

(8) all:允许任意 dropEffect。

不过感觉并没有什么卵用. 而且dropEffect必须在dropenter 事件中设置,effectAllowed必须在dropstart中设置。cao ~
现在可以在html里面直接设置.使用dragzone属性:

属性值 作用
copy 表示将允许的元素放到该元素上时,会将拖拽数据复制到目标元素上。
move 表示将允许的元素放到该元素上时,会将数据移动到目标元素上。
link 表示将允许的元素放到该元素上时,将链接数据到目标元素上。

举例 :

 

总结一下吧,如果你有着热爱新技术的热情,不怕浏览器的SB,视死如归的兼容性。拖拽还是有非常大的用处的。
如果你的leader要求你兼容IE8+的话,拖拽什么的都去屎吧~ .不过,如果你不怕麻烦其实也可以写两份js, 一份给现代浏览器使用,一份给远古的IE用。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78414.html

相关文章

  • 重构-改善既有代码的设计(三)--代码的坏味道

    摘要:坏味道的代码重复代码会自动标注重复的代码。一般都是遇到真实情况后才考虑得到霰弹式修改添加或修改一个功能引发多个类相应修改遇到这种情况可以移动代码,将需要修改的代码都放在同一个类下。被拒绝的遗赠子类应该继承超类的函数和数据。 坏味道的代码 重复代码 idea会自动标注重复的代码。一般重复代码就是可以重构的点。 同一个类的两个函数还有相同的表达式,这时需要提炼出重复代码。 两个互为兄弟的...

    Mr_houzi 评论0 收藏0
  • 重构改善既有的代码设计(代码的坏味道

    摘要:坏的味道指的是应该被修改,被重构的代码,不具有可读性,复用性,判断逻辑复杂,冗余代码。它们通常能指出代码用途和实现手法之间的语义距离。把所有和这个变量相关的代码新建一个类放入。但这往往不够,请反复运用将某些行为移入类,直到者的协议一致为止。 坏的味道:指的是应该被修改,被重构的代码,不具有可读性,复用性,判断逻辑复杂,冗余代码。应该使用各种重构的手法去改变它! Duplicated...

    Code4App 评论0 收藏0
  • 一个有味道的函数

    摘要:所以我们分析这个新需求的效果我们在函数执行到一半时,执行了,的返回值为后续函数的执行返回值。也就是说,我们在中处理,直接调用队列中的下一个函数即可然后监听和回调,即可在当前函数中获取到返回值拿到返回值后就可以执行我们后续的代码。 最近想到了一个自认为很有意思的面试题如何实现一个compose函数。函数接收数个参数,参数均为Function类型,右侧函数的执行结果将作为左侧函数执行的参数...

    megatron 评论0 收藏0
  • 重构:一项常常被忽略的基本功

    摘要:无论如何,单元测试一直是一中非常重要却常常被忽视的技能。在实践中,重构的要求是很高的它需要有足够详尽的单元测试,需要有持续集成的环境,需要随时随地在小步伐地永远让代码处于可工作状态下去进行改善。 showImg(https://segmentfault.com/img/bVbttWF?w=1000&h=528); 五月初的时候朋友和我说《重构》出第 2 版了,我才兴冲冲地下单,花了一个...

    idealcn 评论0 收藏0
  • 模仿飞蛾识别味道的神经网络,说明了为什么飞蛾学习速度远超机器

    摘要:在飞蛾脑中,章鱼胺可以帮助加强产生成功的神经线路。广泛来说,此项研究成果可能给人工神经网络领域带来极大的影响。 作为现代机器学习基石的深度神经网络,虽然模仿的是生物神经网络,但其实这两者之间有着极大的区别。抛开仅有的一些相似处,有些重要的机器学习机制没有任何自然界的版本,而这两者学习过程之间也有着大量的不同。这些区别很有可能解释了为什么机器学习系统在某些领域中的表现远逊于自然系统。就拿昆虫来...

    hizengzeng 评论0 收藏0

发表评论

0条评论

468122151

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<