vlambda博客
学习文章列表

HTML5之拖拽和拖放

拖拽/拖放

拖放(drap&drop)在我们平时的工作中,经常遇到。它表示:抓取对象以后拖放到另一个位置。目前,它是HTML5标准的一部分。

拖放的基本操作

选中=>拖动=>释放
选中


在H5标准中,为了使元素克拖动,把draggable属性设置为true。文本、图片和链接式默认可以拖放的,它们的draggable属性默认被设置了true。

图片和链接按住鼠标左键选中,就可以拖放。

文本只有在被选中的情况下才能拖放。如果显示设置为恩本的draggable属性为true,按住鼠标左边也可以直接拖放。


语法

<element draggle="true|false|auto"></element>

  • true: 可以拖动

  • false: 禁止拖动

  • auto: 跟随浏览器定义是否可以拖动

拖动

每个可拖动的元素,在拖动过程中,都会经历三个过程:

拖动开始=>拖动过程中=>拖动结束


HTML5之拖拽和拖放


注意:dragenter和dragover事件的默认行为是拒绝接受任何被拖放的元素。因此,我们必须阻止浏览器这种默认行为。e.prevenDefault();

释放

到达目的地之后,释放元素事件

HTML5之拖拽和拖放

看个例子演示每个API

<!DOCTYPE HTML><html> <head> <title>拖放示例-文本</title> </head> <style> #current{ border: 1px solid #000; padding: 20px; margin-bottom: 20px; } #target{ border: 1px solid #f00; width: 400px; height: 400px; } .box{ width: 100px; height: 100px; border: 1px solid #FF6700; }</style> <body> <p>不能被拖拽的文字</p> <div id="current"> <div class="text" id="text"> <p draggable="true">可拖拽的文字</p> <img src="img_submit.gif" alt=""> <div class="box" draggable="true"></div> </div> </div> <div id="target"></div> <script> var text = document.getElementById('text'); var target = document.getElementById('target'); text.ondragstart = function(event){ console.log('元素开始被拖动'); } text.ondrag = function(e){ // console.log('一直被拖拽着'); } text.ondragend = function(e){ console.log('拖拽操作完成时触发'); } target.ondragenter = function(e){ console.log('进入了所要的目标对象中'); e.preventDefault() } target.ondragover = function(e){ console.log('在目标元素内触发'); e.preventDefault(); } target.ondragleave = function(e){ console.log('拖拽着元素没有放下,并离开目标对象时'); // e.preventDefault(); } target.ondrop = function(event){ console.log('被拖拽元素在目标元素里放下是触发'); event.preventDefault(); }</script> </body></html>

效果展示:

HTML5之拖拽和拖放

由上个例子我们可以看出我们确实实现了拖放的功能,猜想:能否让我们拖拽的元素放到指定的目标对象上呢?答案是可以的,如果想实现该功能,就要学一下DataTransfer对象了

DataTransfer对象

在进行拖放操作时,DataTransfer对象用来保存,通过拖放操作,拖动到浏览器的数据。它可以保存一项或多项数据、一种或者多种数据类型。

event.DataTransfer
方法

【1】DataTransfer.setData()

该方法用来设置拖动操作的当前数据

语法:

DataTransfer.setData(format,data);
  • format 拖动数据的MIME类型,通常text/plaintext/uri-list

  • data 要添加的数据


【2】DataTransfer.getData()


接收指定类型的拖放数据。如果拖放行为没有操作任何数据,则返回一个空字符串。返回值是字符串类型

语法:


dataTransfer.getData(format);
  • format 拖动数据的MIME类型,通常text/plaintext/uri-list


【3】DataTransfer.clearData()

删除给定类型拖动操作的数据。


【4】DataTransfer.setDragImage()

可以使用该方法来拖拽图片


语法:


DataTransfer.setDragImage(img,xOffset,yOffset)
  • img:拖拽图像的当前元素

  • xOffset :图片的横向偏移量

  • yOffset: 图片的纵向偏移量


定义拖动效果


dropEffect属性可以定义完成具体的效果


我们可以定义三种效果:

  1. copy 表示拖动的数据将从其当前位置复制到放置位置。

  2. move 表示拖动的数据将从其当前位置移动到放置位置。

  3. link 表示将在源位置和放置位置之间创建某种形式的关系或连接。


例子:实现复制和移动元素

<!DOCTYPE html><html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> <style> #copy,#move{ border: 1px solid #000; width: 300px; height: 200px; } #copyTarget,#moveTarget{ width: 300px; height: 200px; border: 1px solid #FF0000; } #newId{ width: 200px; height: 50px; border: 1px solid darkcyan; }</style> </head> <body> <h2>使用拖拽实现移动和复制功能</h2> <div draggable="true" id="copy">要复制的元素</div> <div id="copyTarget"></div> <div draggable="true" id="move">要移动的元素</div> <div id="moveTarget"></div> <script type="text/javascript"> window.onload = function() { // 复制 $('copy').ondragstart = handler_dragstart; $('copy').ondragend = handler_dragend; $('copyTarget').ondragover = hander_dragover; $('copyTarget').ondragleave = handler_dragLeave $('copyTarget').ondrop = handler_drop; // 移动 $('move').ondragstart = handler_dragstart; $('move').ondragend = handler_dragend; $('moveTarget').ondragover = hander_dragover; $('moveTarget').ondragleave = handler_dragLeave $('moveTarget').ondrop = handler_drop; function handler_dragstart(event) { console.log('拖拽开始'); // 设置数据 event.dataTransfer.setData('text/plain', event.target.id); // 设置拖动效果 设置既复制又移动 event.effectAllowed = 'copyMove'; } function handler_dragend(event) { // 拖动操作完成时 清空设置的数据 // event.target.style.borderColor = 'black'; event.dataTransfer.clearData(); } // 当被拖动元素在目标元素内时触发 function hander_dragover(event) { event.target.style.background = 'lightblue'; event.preventDefault(); } function handler_drop(event) { event.preventDefault(); // 获取设置的数据 var id = event.dataTransfer.getData('text/plain'); if (id === 'copy' && event.target.id == 'copyTarget') { var nodeCopy = document.getElementById(id).cloneNode(true); nodeCopy.id = 'newId'; event.target.appendChild(nodeCopy); } if(id === 'move' && event.target.id == 'moveTarget'){ event.target.appendChild(document.getElementById(id)); console.log(event.target.children); } } function handler_dragLeave(event) { event.target.style.background = 'white'; event.preventDefault(); } function $(ele) { return document.getElementById(ele); } }</script> </body></html>

效果展示:

例子:实现简单拖拽购物车功能

<html> <head> <meta charset="utf-8" /> <title>使用拖放API将商品拖入购物车</title> <style> body { font-size: 12px } .liT { border-bottom: solid 1px #ccc; background-color: #eee; font-weight: bold } .liF { float: left; margin-right: 5px; } ul { list-style-type: none; padding: 0px; height: 106px; width: 330px } ul li { overflow: hidden; } ul li img { width: 68px; height: 96px; border: solid 1px #ccc; padding: 3px } ul li span { float: left; width: 70px; padding: 5px; }</style> </head> <body> <ul> <li class="liF"> <img src="image01.png" id="img02" alt="42" title="2006作品" draggable="true"> </li> <li class="liF"> <img src="image02.png" id="img03" alt="56" title="2008作品" draggable="true"> </li> <li class="liF"> <img src="image03.png" id="img04" alt="52" title="2010作品" draggable="true"> </li> </ul> <ul id="ulCart"> <li class="liT"> <span>书名</span> <span>定价</span> <span>数量</span> <span>总价</span> </li> </ul> <script type="text/javascript"> pageload(); function $$(id) { return document.getElementById(id); } //自定义页面加载时调用的函数 function pageload() { //获取全部的图书商品 var Drag = document.getElementsByTagName("img"); //遍历每一个图书商品 for (var intI = 0; intI < Drag.length; intI++) { console.log(Drag[intI]); //为每一个商品添加被拖放元素的dragstart事件 Drag[intI].addEventListener("dragstart", function(e) { e.dataTransfer.clearData(); var objDtf = e.dataTransfer; console.log(objDtf); objDtf.setData("text/plain", addCart(this.title, this.alt, 1)); },true); } var Cart = $$("ulCart"); //添加目标元素的drop事件 Cart.addEventListener("drop",function(e) { var objDtf = e.dataTransfer; var strHTML = objDtf.getData("text/plain"); var num = top_(); Cart.innerHTML += strHTML; var lists = document.getElementsByClassName('liC'); for(var i = 0; i < lists.length; i++){ var spans = lists[i].children; console.log(spans); spans[2].innerHTML = num; spans[3].innerHTML = num * spans[1].innerHTML; } e.preventDefault(); e.stopPropagation(); },false); } //添加页面的dragover事件 document.ondragover = function(e) { //阻止默认方法,取消拒绝被拖放 e.preventDefault(); } //添加页面drop事件 document.ondrop = function(e) { //阻止默认方法,取消拒绝被拖放 e.preventDefault(); } //自定义向购物车中添加记录的函数 function addCart(a, b, c) { var strHTML = `<li class = 'liC'> <span>${a}</span> <span class="price">${b}</span> <span class="num">${c}</span> <span class="sum">${b*c}</span> </li>` return strHTML; } //提示输入框 function top_() { var str = prompt("请输入要购买的数量", 1); return str; }</script> </body></html>


作者:前端开发小马哥链接:https://juejin.im/post/6892704842968465416来源:掘金

扫描下方二维码

获取web前端、学习资料视频