HTML5中元素的拖放详解

发布于:2024-09-19 ⋅ 阅读:(123) ⋅ 点赞:(0)

第11章 HTML5中元素的拖放

只要为元素添加draggable属性,就可实现元素的拖放

11.1 拖放基础

11.1.1 使用JavaScript代码实现拖放

1.功能描述

H5页面中,添加两个div,divFrame包含divTitle,用鼠标移到divTitle上时,按下鼠标左键并移动鼠标,可以拖动整个divFrame元素。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用JavaScript代码实现拖放</title>
    <style>
        #divFrame {
            width: 200px;
            height: 100px;
            border: 1px solid;
            position: relative;
        }

        #divTitle {
            border-bottom: 1px solid;
        }

        #divTitle:hover {
            /* cursor: crosshair; */
            /* background-color: gray; */
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }
        var started;
        var initX, initY, offsetX, offsetY;
        function pageload() {
            var divTitle = $$("divTitle");
            var divFrame = $$("divFrame");
            divFrame.style.left = 30 + "px";
            divFrame.style.top = 20 + "px";
            //按下鼠标触发
            divTitle.onmousedown = function (e) {
                started = true;
                initX = parseInt(divFrame.style.left);
                initY = parseInt(divFrame.style.top);
                offsetX = e.clientX;
                offsetY = e.clientY;
            };
            //鼠标移动时触发的事件
            divFrame.onmousemove = function (e) {
                if (started) {
                    var x = e.clientX - offsetX + initX;
                    var y = e.clientY - offsetY + initY;
                    divFrame.style.left = x + "px";
                    divFrame.style.top = y + "px";
                    divTitle.innerHTML = "已拖动";
                }
            };
            //鼠标弹起时触发的事件
            divFrame.onmouseup = function () {
                started = false;
                document.onmousemove = null;
            }
        }
    </script>
</head>

<body onload="pageload();">
    <div id="divFrame">
        <div id="divTitle">请拖动我</div>
    </div>
</body>

</html>
3.页面效果

11.1.2 在HTML5中实现拖放时触发的事件

在H5中拖放很简单,只要将属性draggable设置为true就可以,拖放时触发的相关事件:

  • dragstart:被拖放元素,开始拖放时触发
  • drag:被拖放元素,正在拖放时触发
  • dragenter:经过目标元素,进入某元素时触发
  • dragover:经过目标元素,在某元素内移动时触发
  • dragleave:目标元素,移出时触发
  • drop:目标元素,目标元素完全接收时触发
  • dragend:被拖放对象元素,整个拖放操作结束时触发
1.功能描述

新建两个div,将一个元素拖到另一个元素时,页面触发的重要事件状态。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        #divDrag {
            width: 100px;
            height: 100px;
            border: 1px solid;
        }

        #divArea {
            float: right;
            width: 200px;
            height: 200px;
            border: 1px solid;
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }

        function pageload() {
            var Drag = $$("divDrag");
            var Area = $$("divArea");
            //添加被拖放元素的dragstart事件
            Drag.addEventListener("dragstart", function (e) {
                StatusHandle("元素正在开始拖动。。。")
            });
            //添加目标元素drop事件
            Area.addEventListener("drop", function (e) {
                StatusHandle("元素拖入成功!")
            });
            //添加目标元素的dragleave事件
            Area.addEventListener("dragleave", function (e) {
                StatusHandle("拖动元素正在离开。。。")
            });
        }
        function StatusHandle(message) {
            $$("divTips").innerHTML += message + "<br>";
        }
        //添加页面的dragover事件
        document.ondragover = function (e) {
            //阻止默认方法,取消拒绝被拖放
            e.preventDefault();
        }
        //添加页面的ondrop事件
        document.ondrop = function (e) {
            //阻止默认方法,取消拒绝被拖放
            e.preventDefault();
        }

    </script>
</head>

<body onload="pageload();">
    <div class="wPub">
        <div class="wPub">
            <div id="divDrag" draggable="true">drag</div>
            <div id="divTips">tips:</div>
        </div>
        <div id="divArea">area</div>
    </div>
</body>

</html>
3.页面效果

11.2 dataTransfer对象应用详解

上个案例,被拖放对象没放入目标中,要实现这一功能,需要调用dataTransfer对象。

该对象携带拖放过程中的数据,它拥有许多使用的属性和方法。

dataTransfer对象的属性:
  • effectAllowed:设置或返回被允许操作的效果,包括none,copy,copyLink,copyMove,line,move,all等。
  • dropEffect:设置或返回当前选定的操作效果类型,若不是effectAllowed的允许范围值,则操作失败。
  • items:返回DataTransferItemList对象,即拖动数据。
  • types:返回dragstart事件中设置的数据格式,如果拖动文件,返回Files型字符串。
  • files:返回被拖动文件FileList清单(如果有)
dataTransfer对象的方法:
  • setData(DOMString format,DOMString data):将拖放元素数据存入dataTransfer对象中
  • getData(DOMString format):读取存入dataTransfer对象中的数据
  • setDragImage(Element img,long x,long y):设置拖放过程中的图标
  • clearData(DOMString format):清空dataTransfer对象中指定格式的数据

format形参格式包含如下几种:text/plain(文本文字格式),text/html(HTML页面代码格式),text/xml(XML字符格式),text/url-list(URL格式列表)。

11.2.1 使用setData与getData方法存入与读取拖放数据

1.功能描述

在上一个案例基础上修改代码,当拖放元素触发dragstart事件时,将元素相关数据通过setData()方法存入dataTransfer对象中,在目标接收拖放元素时触发drop事件,该事件中读取dataTransfer对象中存入的数据并放入目标元素中。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用setData与getData方法存入与读取拖放数据</title>
    <style>
        #divDrag {
            width: 100px;
            height: 100px;
            border: 1px solid;
        }

        #divArea {
            float: right;
            width: 200px;
            height: 200px;
            border: 1px solid;
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }
        //自定义返回HTML内容函数
        function RetDragHTMLById(Id) {
            var strHtml = "<div id=" + Id + "></div>";
            return strHtml;
        }

        function pageload() {
            var Drag = $$("divDrag");
            var Area = $$("divArea");
            //添加被拖放元素的dragstart事件
            Drag.addEventListener("dragstart", function (e) {
                var dtf = e.dataTransfer;
                dtf.setData("text/html", RetDragHTMLById(this.id));
            }, false);
            //添加目标元素drop事件
            Area.addEventListener("drop", function (e) {
                var dtf = e.dataTransfer;
                var strHtml = dtf.getData("text/html");
                Area.innerHTML += strHtml;
                e.preventDefault();
                e.stopPropagation();
            }, false);
        }
        //添加页面的dragover事件
        document.ondragover = function (e) {
            //阻止默认方法,取消拒绝被拖放
            e.preventDefault();
        }
        //添加页面的ondrop事件
        document.ondrop = function (e) {
            //阻止默认方法,取消拒绝被拖放
            e.preventDefault();
        }
    </script>
</head>

<body onload="pageload();">
    <div class="wPub">
        <div class="wPub">
            <div id="divDrag" draggable="true">drag</div>
            <div id="divTips">tips:</div>
        </div>
        <div id="divArea">area</div>
    </div>
</body>

</html>
3.页面效果

11.2.2 使用setDragImage方法设置拖放图标

在THML5中,一个元素在被拖放时,还可以改变鼠标的图标,即可以自定义拖放元素时的鼠标图标。要实现这一功能,需要调用dataTransfer对象的setDragImage()方法,调用格式为:

setDragImage(Element img,long x,long y)

其中,参数img是一个元素,表示拖放时显示的元素图标,x表示图标距离鼠标指针的x轴方向的偏移量,y表示图标距离鼠标指针的y轴方向偏移量。

1.功能描述

新创建HTML页面,添加两个

区域,一个作为拖放元素,一个作为目标元素,用于接收拖放来的元素和数据。

选中拖放元素并按住鼠标开始拖放时,鼠标图标将发生变化,拖放完成时,在目标元素中显示“拖动时图标改变”字样。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用setDragImage方法设置拖放图标</title>
    <style>
        #divDrag {
            width: 100px;
            height: 100px;
            border: 1px solid;
        }

        #divArea {
            float: right;
            width: 200px;
            height: 200px;
            border: 1px solid;
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }
        function pageload() {
            var Drag = $$("divDrag");
            var Area = $$("divArea");
            var objImg = document.createElement("img");
            objImg.src = "img/dog.jpg";
            //添加被拖动元素的dragstart事件
            Drag.addEventListener("dragstart", function (e) {
                var objDtf = e.dataTransfer;
                objDtf.setDragImage(objImg, -50, -50);
                objDtf.setData("text/plain", "拖动时改变图标");
            }, false);
            //添加目标元素的drop事件
            Area.addEventListener("drop", function (e) {
                var objDtf = e.dataTransfer;
                var strText = objDtf.getData("text/plain");
                Area.textContent += strText;
                e.preventDefault();
                e.stopPropagation();
            }, false)
            //添加页面的dragover事件
            document.ondragover = function (e) {
                //阻止默认方法,取消拒绝被拖放
                e.preventDefault();
            }
            //添加页面的ondrop事件
            document.ondrop = function (e) {
                //阻止默认方法,取消拒绝被拖放
                e.preventDefault();
            }
        }
    </script>
</head>

<body onload="pageload();">
    <div class="wPub">
        <div class="wPub">
            <div id="divDrag" draggable="true">drag</div>
            <div id="divTips">tips:</div>
        </div>
        <div id="divArea">area</div>
    </div>
</body>

</html>
3.页面效果

11.2.3 使用effectAllowed与dropEffect属性设置拖放效果

结合effectAllowed与dropEffect这两个属性,可以自定义拖放过程中的效果。

effectAllowed用于dragstart事件中,绑定被拖放元素,dropEffect用于绑定目标元素。

1.功能描述

在上面例子中,修改代码,拖放元素触发dragstart事件时,将dataTransfer对象的effectAllowed属性设置为move,为目标添加一个dragover事件,当接收数据时,将dropEffect属性值也设为move,从而实现自定义元素拖放效果。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用effectAllowed与dropEffect属性设置拖放效果</title>
    <style>
        #divDrag {
            width: 100px;
            height: 100px;
            border: 1px solid;
        }

        #divArea {
            float: right;
            width: 200px;
            height: 200px;
            border: 1px solid;
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }
        function pageload() {
            var Drag = $$("divDrag");
            var Area = $$("divArea");
            var objImg = document.createElement("img");
            objImg.src = "img/dog.jpg";
            //添加被拖动元素的dragstart事件
            Drag.addEventListener("dragstart", function (e) {
                var objDtf = e.dataTransfer;
                /* objDtf.setDragImage(objImg,-50,-50);
                objDtf.setData("text/plain","拖动时改变图标"); */
                objDtf.effectAllowed = "copy";
                objDtf.setData("text/plain", "拖动时动画效果")
            }, false);
            //添加目标元素的dragover事件
            Area.addEventListener("dragover", function (e) {
                var objDtf = e.dataTransfer;
                objDtf.dropEffect = "copy";
                e.preventDefault();
            }, false)
            //添加目标元素的drop事件
            Area.addEventListener("drop", function (e) {
                var objDtf = e.dataTransfer;
                var strText = objDtf.getData("text/plain");
                Area.textContent += strText;
                e.preventDefault();
                e.stopPropagation();
            }, false)
            //添加页面的dragover事件
            document.ondragover = function (e) {
                //阻止默认方法,取消拒绝被拖放
                e.preventDefault();
            }
            //添加页面的ondrop事件
            document.ondrop = function (e) {
                //阻止默认方法,取消拒绝被拖放
                e.preventDefault();
            }
        }
    </script>
</head>

<body onload="pageload();">
    <div class="wPub">
        <div class="wPub">
            <div id="divDrag" draggable="true">drag</div>
            <div id="divTips">tips:</div>
        </div>
        <div id="divArea">area</div>
    </div>
</body>

</html>
3.页面效果

11.3 拖放应用实战

拖放功能重要,借助API可以实现相对复杂的功能与特效,例如:电商平台中的购物车,可以将选中的商品以拖放的方式放入购物车中,同时接收拖来的数据,检测重复性并自动计价。在相册管理中的图片以拖放的方式放入回收站中,改变回收站图标样式,删除图片。

11.3.1 购物车的实现

通常情况,除了点击商品的购买练级额,也可以拖放商品到购物车中。

1.功能描述

创建H5,页面中展示4件图书商品,用户可以任选一件,按住鼠标,以拖放的方式将选择的商品放入购物车中,同时,购物车接收拖来的商品数据,自动增加一条选择记录,并显示商品的基本信息。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>拖放购物车</title>
    <style>
        ul#ulBook {
            height: 200px;
            clear: both;
        }

        ul#ulBook li {
            list-style-type: none;
            float: left;
            margin: 5px;
            padding: 3px;
            text-align: center;
            border: 1px solid;
            width: 60px;
            height: 80px;
        }

        #ulCart {
            height: 200px;
            list-style-type: none;
            /* border: 1px dotted; */
        }

        .lg {
            background-color: lightgray;
        }

        span {
            font-weight: bold;
            display: inline-block;
            width: 100px;
            border: 1px solid;
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }

        function pageload() {
            //获取全部图书商品
            var Drag = document.getElementsByTagName("img");
            //遍历每个图书商品
            for (var i = 0; i < Drag.length; i++) {
                //为每个商品添加dragstart事件
                Drag[i].addEventListener("dragstart", function (e) {
                    var objDtf = e.dataTransfer;
                    objDtf.setData("text/html", addCard(this.title, this.alt, 1));
                }, false)
            }
            var Cart = $$("ulCart");
            //添加目标元素的drop事件
            Cart.addEventListener("drop", function (e) {
                var objDtf = e.dataTransfer;
                var strHtml = objDtf.getData("text/html");
                Cart.innerHTML += strHtml;
                e.preventDefault();
                e.stopPropagation();
            }, false);
        }
        //添加页面dragover事件
        document.ondragover = function (e) {
            e.preventDefault();
        }
        //添加页面drop事件
        document.ondrop = function (e) {
            e.preventDefault();
        }
        //自定义向购物车中添加记录的函数
        function addCard(a, b, c) {
            var strHtml = "<li class='liC'>";
            strHtml += "<span>" + a + "</span>";
            strHtml += "<span>" + b + "</span>";
            strHtml += "<span>" + c + "</span>";
            strHtml += "<span>" + b * c + "</span></li>";
            return strHtml;
        }
    </script>
</head>

<body onload="pageload();">
    <ul id="ulBook">
        <li class="liF">
            <img src="img/实战.jpg" id="img02" alt="42" title="2020年作品" draggable="true" />
        </li>
        <li class="liF">
            <img src="img/JS高级.jpg" id="img03" alt="56" title="2021年作品" draggable="true" />
        </li>
        <li class="liF">
            <img src="img/并发编程.jpg" id="img04" alt="52" title="2022年作品" draggable="true" />
        </li>
        <li class="liF">
            <img src="img/计算机网络.jpg" id="img05" alt="59" title="2023年作品" draggable="true" />
        </li>
    </ul>
    <ul id="ulCart">
        <li>
            <span class="lg">书名</span><span class="lg">定价</span><span class="lg">数量</span><span class="lg">总价</span>
        </li>
    </ul>
</body>

</html>

</body> </html>

3.页面效果

11.3.2 相册的管理

除了上述应用,还可以将相册中某张图片以拖放的方式放入回收站,从而实现管理相册的功能。

1.功能描述

新建H5,以列表方式展示相册中的3张图片,用户可以任选一张,按住鼠标,以拖动的方式放入右下角回收站,拖放成功后,将在页面中显示删除图片的记录数,同时回收站样式也发生相应变化。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用拖放API将图片拖入回收站</title>
    <style>
        * {
            list-style-type: none;
        }

        ul {
            width: 400px;
            height: 200px;
            border: 1px dotted;
        }

        ul li {
            float: left;
            margin: 5px;
            padding: 3px;
            text-align: center;
            border: 1px solid;
            width: 60px;
            height: 80px;
        }

        #divRecycle {
            height: 200px;
            width: 200px;
            border: 1px solid;
            border-radius: 100px;
            background-image: url(img/空杯.png);
        }

        #divRecycle.HaveRyl {
            background-image: url(img/实杯.png);
        }
    </style>
    <script>
        function $$(id) {
            return document.getElementById(id);
        }
        var intDeleteNum = 0;
        function pageload() {
            //获取全部图片信息
            var Drag = document.getElementsByTagName("li");
            //遍历图片
            for (var i = 0; i < Drag.length; i++) {
                //为每一张图片添加dragstart事件
                Drag[i].addEventListener("dragstart", function (e) {
                    var dtf = e.dataTransfer;
                    dtf.setData("text/plain", this.id);
                }, false)
            }
            var Recy = $$("divRecycle");
            //添加目标元素的drop事件
            Recy.addEventListener("drop", function (e) {
                var dtf = e.dataTransfer;
                var intVal = dtf.getData("text/plain");
                Drag_Event(intVal);
                Recy.className = "HaveRyl";
            }, false);
        }
        //添加页面dragover事件
        document.ondragover = function (e) {
            e.preventDefault();
        }
        //添加页面drop事件
        document.ondrop = function (e) {
            e.preventDefault();
        }
        function Drag_Event(id) {
            var Node = $$(id);
            Node.parentNode.removeChild(Node);
            intDeleteNum++;
            $$("pStatus").innerHTML = "已成功删除" + intDeleteNum + "张图片!";
        }
    </script>
</head>

<body onload="pageload();">
    <div class="wPub">
        <ul>
            <li id="li01">
                <img src="img/实战.jpg" draggable />
            </li>
            <li id="li02">
                <img src="img/JS高级.jpg" draggable />
            </li>
            <li id="li03">
                <img src="img/并发编程.jpg" draggable />
            </li>
        </ul>
        <p id="pStatus">提示:</p>
        <div id="divRecycle"></div>
    </div>
</body>

</html>
3.页面效果

 对应文档:【有道云笔记】《HTML5实战》
https://note.youdao.com/s/3ubs1KG8

如需源码,请私信我!!!


网站公告

今日签到

点亮在社区的每一天
去签到