其实HTML5就是新增一些有用的API
让我们更轻松的开发
从而把更多精力都放在业务逻辑上来
这些API的使用也非常简单
不过我的记性不太好
所以还是以博客的形式记录下来(手动滑稽)
今天就来写一下这个拖拽API

默认拖拽

说起拖放,其实最早实现拖放功能的还是IE(IE4)
H5就是在IE实例的基础上指定的拖拽规范
在浏览器中,是有默认拖拽的
比如说图片的拖拽

html5在Android中不能拖拽 html5拖拽api_html5在Android中不能拖拽

选中文本的拖拽

html5在Android中不能拖拽 html5拖拽api_html5在Android中不能拖拽_02

链接的拖拽

html5在Android中不能拖拽 html5拖拽api_html5在Android中不能拖拽_03

元素拖拽

浏览器默认允许我们拖拽图像、文本以及链接
让其它元素被拖动也是可以实现的
只需要在元素标签上添加一个属性

<div draggable="true"></div>

当拖拽这个元素的时候,浏览器就会以半透明复本的方式显示

拖拽事件

拖拽事件应该分为两类
一类是被拖拽元素触发的事件
另一类是拖放目标元素触发的事件

<div id="source" draggable="true"></div>
<div id="target"></div>  <!-- 样式略 -->
var source = document.getElementById('source');
var target = document.getElementById('target');

拖拽元素

拖拽元素的时候,被拖拽元素会触发以下事件

  • dragstart
  • drag
  • dragend

当鼠标点中元素并且开始移动时,就会触发dragstart事件(类比mousedown)
拖拽过程中会持续不断地触发drag事件(类比mousemove)
松开鼠标取消拖拽时就会触发dragend事件(类比mouseup)

source.ondragstart = function(){
  console.log('开始拖拽');
}
source.ondrag = function(){
  console.log('拖拽中');
}
source.ondragend = function(){
  console.log('拖拽结束');
}

html5在Android中不能拖拽 html5拖拽api_html5在Android中不能拖拽_04

目标元素

当拖拽的元素拖到一个目标元素上时,目标元素会触发以下事件

  • dragenter
  • dragover
  • dragleave
  • drop

拖拽元素到目标上,就会触发dragenter事件(类比mouseover)
当拖动元素在目标元素中,就会持续触发dragover事件
离开目标元素,触发dragleave事件(类比mouseout)
若拖放元素到了目标元素中(在目标元素中松开鼠标),就会触发drop事件而不会触发dragleave事件

target.ondragenter = function(){
  console.log('拖动进入目标元素');
}
target.ondragover = function(){
  console.log('目标元素中拖拽');
}
target.ondragleave = function(){
  console.log('拖动离开目标元素');
}
target.ondrop = function(){
  console.log('拖放');
}

html5在Android中不能拖拽 html5拖拽api_拖拽_05


这时我们会发现元素拖放到目标元素中时
并没有触发drop事件

html5在Android中不能拖拽 html5拖拽api_拖拽_06

我们看到了一个特殊的光标(圆环+反斜线)
意思就是无效的拖放
所以导致没有触发drop事件
也就是说元素默认是不能够拖放
只要我们在目标元素的dragover事件中取消默认事件就可以解决问题

target.ondragover = function(e){
  console.log('目标元素中拖拽');
  e.preventDefault(); //增
}

数据交换

只是简单的拖放毫无意义
我们需要进行数据交换
而这个用语数据交换的对象就是事件对象的属性dataTransfer
dataTransfer的两个核心方法是setData()和getData()
setData()用于设置数据,getData()用语接收数据

event.dataTransfer.setData('text','some text');

var text = event.dataTransfer.getData('text');
//保存在dataTransfer中的数据只能在drop事件处理函数中处理

如果我们拖拽了选中文本
那么浏览器默认就会调用dataTransfer.setData,设置对应文本数据

setData()和getData()就是数据类型的字符串
IE定义的数据类型除了“text”文本类型还有“URL”
H5对它进行了扩展,可以指定各种MIME类型
但为了向后兼容,它同样支持“text”和“URL”
它们会被分别映射为“text/plain”和“text/uri-list”

如果数据保存为URL,浏览器会做特殊处理,把它当成网页链接
(所以拖拽链接到另外的浏览器窗口就会打开网页)


必要的话,我们可以手动保存需要传输的数据

var source = document.getElementById('source');
var target = document.getElementById('target');
source.ondragstart = function(e){
  e.dataTransfer.setData('text','传递文本数据');
}
target.ondragover = function(e){
  e.preventDefault();
}
target.ondrop = function(e){
  console.log(e.dataTransfer.getData('text'));
}

html5在Android中不能拖拽 html5拖拽api_数据_07

拖拽设置

在dataTransfer中还有两个重要的属性
dropEffecteffectAllowed

dropEffect

dropEffect属性值为字符串,表示被拖动元素可以执行哪一种放置行为
要使用这个属性,必须在dragenter事件处理函数中设置

  • none 不能把元素拖放至此(除文本框外全部元素的默认值)
  • move 移动到目标
  • copy 复制到目标
  • link 目标打开拖动元素(拖动元素必须是链接并有URL)

effectAllowed

effectAllowed属性值也是字符串,表示允许拖动元素哪种dropEffect
要使用这个属性,必须在dragst事件处理函数中设置

  • uninitialized 没有设置任何拖放行为
  • none 不能由任何行为
  • copy 仅允许dropEffect值为copy
  • link 仅允许dropEffect值为link
  • move 仅允许dropEffect值为move
  • copyLink 允许dropEffect值为copy和link
  • copyMove 允许dropEffect值为copy和move
  • linkMove 允许dropEffect值为link和move
  • all 允许任意dropEffect





 拖拽案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>张高伟拖放api</title>
    <style>
        #mydiv{
            width: 200px;
            height: 200px;
            border: 1px solid indianred;
            background-color: #5c2699;
        }

        #target{
            width: 500px;
            height: 500px;
            border: 1px solid indianred;
            background-color: #c0c0c0;
        }
        .item{
            background-color: cadetblue;
            border: 1px solid cornsilk;
        }
    </style>
</head>
<body>
<!--<div id="mydiv" draggable="true"></div>-->
<!--<div id="target" draggable="true"></div>-->


<ul class="parent_url">
    <li draggable="true" class="item">张高伟</li>
    <li draggable="true" class="item">李翠翠</li>
    <li draggable="true" class="item">王三</li>
    <li draggable="true" class="item">赵武</li>
    <li draggable="true" class="item">李四</li>
</ul>
</html>
<script>

    //    var source=document.getElementById('mydiv');
    //    var target=document.getElementById('target');
    //
    //    source.ondragstart = function(){
    //        console.log('开始拖拽');
    //    }
    //    source.ondrag = function(){
    //        console.log('拖拽中');
    //    }
    //    source.ondragend = function(){
    //        console.log('拖拽结束');
    //    }
    //
    //
        target.ondragenter = function(){
            console.log('拖动进入目标元素');
        }
    //    target.ondragover = function(){
    //        console.log('目标元素中拖拽');
    //        return false;
    //    }
        target.ondragleave = function(){
            console.log('拖动离开目标元素');
        }
    //    target.ondrop = function(){
    //        console.log('拖放');
    //        this.appendChild(source)
    //    }





    //遍历节点
    var item=document.getElementsByClassName('item');
    //父级
    var parent_url=document.getElementsByClassName('parent_url');

    for(var i=0,len=item.length;i<len;i++){
        //设置ID方便取
        item[i].id='mydiv'+i;
        //每个拖放
        item[i].ondragstart = function(e){
            //存储id
            e.dataTransfer.setData('id',this.id)
        };
        //放之前取消默认事件
        item[i].ondragover = function(){
            return false;
        };
        //放事件
        item[i].ondrop = function(e){
            //去除拖放开始的ID
            //console.log(e.dataTransfer.getData('id'))
            //放到的位置
            console.log(this)
            var tuo_id=e.dataTransfer.getData('id');
            var tuo=document.getElementById(tuo_id);
            //使用insertBefore 达到换位置效果
            parent_url[0].insertBefore(tuo,this)
            this.style.borderTop="2px solid cornsilk"

        }

        //拖放中
        item[i].ondragenter = function(){
            this.style.borderTop="2px solid black"
        }

        //离开
        item[i].ondragleave = function(){
            this.style.borderTop="2px solid cornsilk"
        }
    }

</script>


拖拽图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>张高伟拖放api</title>
    <style>
        #mydiv{
            width: 200px;
            height: 200px;
            border: 1px solid indianred;
            background-color: #5c2699;
        }

        #target{
            width: 500px;
            height: 500px;
            border: 1px solid indianred;
            background-color: #c0c0c0;
        }
        .item{
            background-color: cadetblue;
            border: 1px solid cornsilk;
        }
    </style>
</head>
<body>
<!--<div id="mydiv" draggable="true"></div>-->
<!--<div id="target" draggable="true"></div>-->


<!--<ul class="parent_url">-->
    <!--<li draggable="true" class="item">张高伟</li>-->
    <!--<li draggable="true" class="item">李翠翠</li>-->
    <!--<li draggable="true" class="item">王三</li>-->
    <!--<li draggable="true" class="item">赵武</li>-->
    <!--<li draggable="true" class="item">李四</li>-->
<!--</ul>-->
</html>
<script>

    //    var source=document.getElementById('mydiv');
    //    var target=document.getElementById('target');
    //
    //    source.ondragstart = function(){
    //        console.log('开始拖拽');
    //    }
    //    source.ondrag = function(){
    //        console.log('拖拽中');
    //    }
    //    source.ondragend = function(){
    //        console.log('拖拽结束');
    //    }
    //
    //
        target.ondragenter = function(){
            console.log('拖动进入目标元素');
        }
    //    target.ondragover = function(){
    //        console.log('目标元素中拖拽');
    //        return false;
    //    }
        target.ondragleave = function(){
            console.log('拖动离开目标元素');
        }
    //    target.ondrop = function(){
    //        console.log('拖放');
    //        this.appendChild(source)
    //    }





//    //遍历节点
//    var item=document.getElementsByClassName('item');
//    //父级
//    var parent_url=document.getElementsByClassName('parent_url');
//
//    for(var i=0,len=item.length;i<len;i++){
//        //设置ID方便取
//        item[i].id='mydiv'+i;
//        //每个拖放
//        item[i].ondragstart = function(e){
//            //存储id
//            e.dataTransfer.setData('id',this.id)
//        };
//        //放之前取消默认事件
//        item[i].ondragover = function(){
//            return false;
//        };
//        //放事件
//        item[i].ondrop = function(e){
//            //去除拖放开始的ID
//            //console.log(e.dataTransfer.getData('id'))
//            //放到的位置
//            console.log(this)
//            var tuo_id=e.dataTransfer.getData('id');
//            var tuo=document.getElementById(tuo_id);
//            //使用insertBefore 达到换位置效果
//            parent_url[0].insertBefore(tuo,this)
//            this.style.borderTop="2px solid cornsilk"
//
//        }
//
//        //拖放中
//        item[i].ondragenter = function(){
//            this.style.borderTop="2px solid black"
//        }
//
//        //离开
//        item[i].ondragleave = function(){
//            this.style.borderTop="2px solid cornsilk"
//        }
//    }


    //获取整个html
    var html=document.documentElement;
    //放之前取消默认事件
    html.ondragover = function(){
        return false;
    };

    html.ondrop = function(e){
        //禁止图片新链接打开
        e.preventDefault();
        //表示文件
        // console.log(e.dataTransfer.files)
        //图片
        console.log(e.dataTransfer.files[0])


        if(e.dataTransfer.files[0].type.indexOf('image')==-1){
            alert('格式错误')
            return false;
        }

        //创建图像
        var image=new  Image();
        //获取图片路径
        image.src=window.URL.createObjectURL(e.dataTransfer.files[0])

        image.style.top=e.pageY+'px'
        image.style.left=e.pageX+'px'
        image.style.height='200px'
        image.style.width='200px'
//        console.log(e.pageY)
//        console.log(e.pageX)
        //设置class名字
        image.className='';
        //将图片添加进去
        document.body.appendChild(image)
    }

</script>