HTML5高阶实例之Drag&Drop

最新更新时间:2018年3月27日21:53:27
《猛戳-查看我的博客地图-总有你意想不到的惊喜》
1、原生拖放-概述

对于拖放事件而言,默认情况下,浏览器不会在拖动期间改变被拖动元素的外观,但你可以自己修改。不过,大多数浏览器会为正被拖动的元素创建一个半透明的副本,这个副本始终随着光标移动。如下图所示。
默认情况下,图片、链接和文本是可以拖动的,也就是说img标签、a标签和选中的文字可以被拖动。
HTML5为所有HTML元素规定了一个draggable属性,img标签、a标签的默认值是true,其他元素默认值是false。

这里写图片描述

所有元素都支持放置目标事件,但默认是不允许放置的,即默认不会触发drop事件。如果想让某元素成为有效的放置目标,需要重写dragenter、dragover、drop事件。

2、使用注意事项
相关事件如下表格
事件名称简要描述是否必须重写
dragstart按下并移动鼠标,被拖动元素此时触发该事件,触发一次
dragenter元素拖动到放置目标上,触发一次
dragover被拖动元素进入放置目标的范围内移动时,持续触发多次
drop被拖动元素放入了放置目标中,触发一次
dataTransfer对象

dataTransfer对象,它是事件对象的一个属性,用于从被拖动元素放置目标传递字符串格式的数据。由于它是事件对象的属性(event.dataTransfer),所以只能在拖放事件的事件处理程序中访问。dataTransfer对象两个主要方法:
event.dataTransfer.setData();
event.dataTransfer.getData();
注意:在dragstart事件中通过event.dataTransfer.setData(‘text’,‘wanshaobo’)保存在dataTransfer对象中的数据,只能在drop事件处理程序中读取event.dataTransfer.getData(‘text’)

3、实例一

概述:实现任务进度完成情况的可视化方案,包括未开始、进行中和已完成,任务标签可以在不同进度框中随意拖放。
代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>HTML5-drag&drop</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    #container{
        /*font-size: 0;*/
        clear: both;
    }
    .dropTarget{
        width: 200px;
        height: 500px;
        background: #fff;
        border: 1px solid deeppink;
        /*display: inline-block;*/
        margin-left: 20px;
        margin-top: 20px;
        float: left;
        text-align: center;
    }
    #draggable{
        /*font-size: 0;*/
        /*子元素人为设置为inline-block,父元素需要设置0字号以消除子元素间距*/
    }
    .child{
        width: 200px;
        height: 40px;
        color: #fff;
        font-size: 14px;
        text-align: center;
        line-height: 40px;
        border-radius: 20px;
        margin-top: 5px;
    }
    .child-img{
        width: 100px;
        height: 100px;
    }
    .title{
        margin-left: 20px;
        float: left;
        width: 200px;
        text-align: center;
        border: 1px solid #11baaa;
        line-height: 30px;
        border-radius: 15px;
        color: #aaccbb;
    }
    .clearBoth{
        clear: both;
    }
    #top-title{
        width: 640px;
        text-align: center;
        line-height: 50px;
        font-size: 22px;
        color: deeppink;
        font-weight: bolder;
        margin-left: 20px;
    }
</style>
<body>
<div id="top-title">我的一天</div>
<div class="clearBoth">
    <div class="title">准备做的事情</div>
    <div class="title">正在做的事情</div>
    <div class="title">已做完的事情</div>
</div>
<div id="container">
    <div id="start" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">
        <img id="five" class="child-img" src="./wsb.jpg" alt="" ondragstart="dragstart(event)">
        <div id="one" class="child" style="background: #ff7777" draggable="true" ondragstart="dragstart(event)">洗漱</div>
        <div id="two" class="child" style="background: #aaccbb" draggable="true" ondragstart="dragstart(event)">吃早饭</div>
        <div id="three" class="child" style="background: #ad8888" draggable="true" ondragstart="dragstart(event)">坐公交去上班</div>
        <div id="four" class="child" style="background: #f00aaa" draggable="true" ondragstart="dragstart(event)">到公司了打卡</div>
    </div>
    <div id="doing" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">

    </div>
    <div id="end" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">

    </div>
</div>
</body>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    function dragstart(ev) {
        ev.dataTransfer.setData("Text",ev.target.id);//获取拖动元素实例
    }
    function dragenter(ev) {
        ev.preventDefault();//dragenter事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
    }
    function dragover(ev) {
        ev.preventDefault();//dragover事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
    }
    //必须重写dragenter事件和dragover事件,阻止这两个事件的默认行为触发,才能触发drop事件
    function drop(ev) {
        ev.preventDefault();//在Firefox3.5+中,放置事件的默认行为是打开被放到放置目标上的URL,为了兼容性,需要取消drop事件的默认行为
        var data = ev.dataTransfer.getData("Text");
        ev.target.appendChild(document.getElementById(data));
    }
</script>
</html>

作品如下

这里写图片描述

4、实例二

概述:子元素在父元素中随意拖放,但不能超出父元素。
分析:子元素超出父元素分为两种情况,第一,释放子元素时鼠标已经出界;第二,释放子元素时鼠标没有出界,但子元素出界;
代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>HTML5-drag&drop</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .dropTarget{
        width: 600px;
        height: 400px;
        background: #fff;
        border: 1px solid deeppink;
        margin-left: 20px;
        margin-top: 40px;
    }
    #child{
        width: 100px;
        height: 60px;
        position: relative;
        box-sizing: border-box;
        background: #ff7777;
    }
</style>
<body>
<div id="start" class="dropTarget" ondrop="drop(event)" ondragover="dragover(event)">
    <div
        id="child"
        onmousedown="mousedown(event)"
        draggable="true"
        ondragstart="dragstart(event)"
        ondrag="drag(event)"
        ondragend="dragend(event)"

    ></div>
</div>
</body>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    var relativeX = 0;//可移动元素相对于父元素的位置
    var relativeY = 0;
    var mousedownX = 0;//鼠标在可移动元素上单击时,相对于该元素的位置 0 < x < 100
    var mousedownY = 0;
    var draggableEle = document.getElementById('child');
    function dragstart(ev) {
        //ev.dataTransfer.setData("Text",ev.target.id);//获取拖动元素实例
    }
    function drag(ev) {

    }
    function mousedown(ev) {
        //ev对象下offsetX offsetY鼠标在该移动元素上的位置
        mousedownX = ev.offsetX;
        mousedownY = ev.offsetY;
    }
    function dragend(ev) {
        //ev对象下screenX clientX pageX x都相同
        //ev对象下clientY pageY y都相同,相对于可视区域的垂直位置;但screenY不同,screenY是相对于屏幕的垂直位置
        //ev对象下offsetX offsetY鼠标移动的位移+鼠标在该移动元素上的位置
        //DOM元素属性操作方法 getAttribute()、setAttribute()、removeAttribute()
        //DOM元素样式操作方法 elm.style.color 获取和赋值
        relativeX += ev.offsetX - mousedownX;
        relativeY += ev.offsetY - mousedownY;
        //draggableEle.setAttribute('style','left:'+ relativeX + 'px;top:' + relativeY + 'px');//失效,因为重置了所有属性,丢失了宽高
        //水平方向
        if(ev.screenX <= 20 || ev.screenX >= 620){//鼠标出界
            if(ev.screenX <= 20){//父元素相对于屏幕的margin-left: 20px;
                draggableEle.style.left = 0 + 'px';
                relativeX = 0;//注意:此处没有px
            }else if(ev.screenX >= 620){//父元素宽600 + 20
                draggableEle.style.left = 500 + 'px';//600-100
                relativeX = 500;//注意:此处没有px
            }else{
                draggableEle.style.left = relativeX + 'px';
            }
        }else{//元素出界鼠标没有出界
            if(ev.screenX <= mousedownX + 20){
                draggableEle.style.left = 0 + 'px';
                relativeX = 0;//注意:此处没有px
            }else if(ev.screenX >= mousedownX + 520){//600-100+20
                draggableEle.style.left = 500 + 'px';
                relativeX = 500;//注意:此处没有px
            }else{
                draggableEle.style.left = relativeX + 'px';
            }

        }
        //垂直方向
        if(ev.pageY <= 20 || ev.pageY >= 440){//鼠标出界
            if(ev.pageY <= 40){
                draggableEle.style.top = 0 + 'px';
                relativeY = 0;//注意:此处没有px
            }else if(ev.pageY >= 440){
                draggableEle.style.top = 340 + 'px';
                relativeY = 340;//注意:此处没有px
            }else{
                draggableEle.style.top = relativeY + 'px';
            }
        }else{//元素出界鼠标没有出界
            if(ev.pageY <= mousedownY + 40){
                draggableEle.style.top = 0 + 'px';
                relativeY = 0;//注意:此处没有px
            }else if(ev.pageY >= mousedownY + 380){//400-60+40
                draggableEle.style.top = 340 + 'px';
                relativeY = 340;//注意:此处没有px
            }else{
                draggableEle.style.top = relativeY + 'px';
            }
        }
    }
    //必须重写dragenter事件和dragover事件,阻止这两个事件的默认行为触发,才能触发drop事件
    function dragenter(ev) {
        ev.preventDefault();//dragenter事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
    }
    function dragover(ev) {
        ev.preventDefault();//dragover事件的默认行为是该元素不允许其他元素放入,阻止默认行为之后,其他元素即可放入
    }
    //在Firefox3.5+中,放置事件的默认行为是打开被放到放置目标上的URL,为了兼容性,需要取消drop事件的默认行为
    function drop(ev) {
        ev.preventDefault();
    }
</script>
</html>

作品如下

这里写图片描述

感谢阅读,欢迎评论^-^

打赏我吧^-^

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值