拖拽/拖放

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

拖放的基本操作

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


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

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

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


语法

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


  • true: 可以拖动

  • false: 禁止拖动

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

拖动

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

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


HTML5之拖拽和拖放_HTML5


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

释放

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

HTML5之拖拽和拖放_HTML5_02

看个例子演示每个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之拖拽和拖放_HTML5_03

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

效果展示:

HTML5之拖拽和拖放_HTML5_04

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

<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>                            <span>${a}</span>                            <span>${b}</span>                            <span>${c}</span>                            <span>${b*c}</span>                  </li>`                return strHTML;            }            //提示输入框            function top_() {                var str = prompt("请输入要购买的数量", 1);                return str;            }</script>    </body></html>


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