美文网首页让前端飞程序员技术干货
拖放API中的drag和drop实战

拖放API中的drag和drop实战

作者: 楼心漫 | 来源:发表于2017-07-25 19:18 被阅读313次
    漫山遍野

    原文地址:→传送门

    写在前面

    在HTML5之前,实现拖放功能需要借助mousedown/mousemove/mouseover/mouseout/mouseup等鼠标事件来完成,HTML5中拖放API的出现使很多事情变简单。下面是做笔记做笔记~

    注:未来得及做兼容,请在chrome中打开。

    拖放过程

    1. 拖放:包括拖拽(drag)和释放(drop)

    2. 拖放中涉及两个元素,分别是:源对象和目标对象,如下图
      源对象是被拖拽的元素,目标对象是要释放到的接收元素。


      源对象和目标对象
    3. 拖放事件:

    拖放事件流(图片来自H5程序设计书)

    拖放事件流为拖放操作开始后触发的一系列事件,分为以下两类:

    发生在源对象上的事件

    dragstart:用户开始拖动页面中的某个元素时触发的事件
    drag: 源对象在拖拽过程中持续触发的事件
    dragend:拖动完成时触发的事件,一般用于清空拖动过程中的状态等。 
    

    发生在目标对象上的事件

    dragenter:源对象进入到目标对象时,会触发目标对象的ondragenter事件
    dragleave:源对象移除之前调用了dragenter的元素时,目标元素触发的事件
    dragover:源对象进入目标对象后持续触发的事件
    drop:用户释放鼠标时,drop会在目标对象上被调用
    

    4.设置元素可拖动

    dragable = "true"
    

    5.传输和控制--dataTransfer

    dataTransfer对象可用于每个拖放事件中。用于获取和设置实际放置的数据,主要属性及方法如下:

    setData(format,data):在dragstart事件中调用此函数可以注册一个MIME类型格式的传输项。
    getData(format):可以获取指定类型的注册数据项。
    types:属性以数组形式返回所有当前注册的格式。
    items:返回所有项机器相关格式列表
    files:返回与放置相关的所有文件
    clearData():不带参则清空所有注册数据,带参则移除指定注册项
    …………等等
    

    来点儿小栗子

    说小栗子前说下两点:

    • 触发dragover事件时,需要使用preventDefault()方法阻止默认事件,drag事件才能正常触发
    • dataTransfer中的files属性用到了File API规范的子集,files存放了文件列表,files支持下列属性:
    name:带有扩展名的文件全名
    type:文件的MIME类型
    size:以字节为单位的文件大小
    lastModifiedDate:最后一次修改文件内容的时间戳
    
    • 下面会用到的FileReader对象详细请移步
      FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

    其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果.

    1. 简单的节点拖放
      可将任意节点拖放到其他元素上,并插入到目标元素的前面
      拖放前后:


      拖放节点效果

    主要代码:

     /*目标对象上触发的dragove事件*/
        drag.addEventListener('dragover', function (e) {
            e.preventDefault(); //阻止默认动作
        })
      
        /*源对象释放,目标对象上触发的事件*/
        drag.addEventListener('drop', function (e) {
            ele.classList.remove('draging');
            if (e.target.nodeName === 'LI') {
                e.target.parentNode.insertBefore(ele, e.target); //将源对象元素插入到目标元素前面
            }
        })
    

    2.节点清除
    可将龙猫丢进垃圾桶,即清除img元素节点
    丢龙猫前后:


    丢龙猫前后

    主要代码:

    <h3>拖动龙猫到垃圾桶后从DOM树中删除子元素</h3>  
          ![](./img/default.png)  
          <hr/>  
          ![](./img/01.jpeg)  
          ![](./img/02.jpg)  
          ![](./img/03.jpeg)  
          
          <script>  
          
            //为源对象添加事件监听 —— 记录拖动了哪一个源对象  
            var imgs = document.querySelectorAll('.imgs'); 
            var target = document.querySelector('#bin');
    
            for(var i=0; i<imgs.length; i++){   
              var pic = imgs[i];  
              pic.ondragstart = function(e){ //开始拖动源对象  
                e.dataTransfer.setData('imgID',this.id);//保存被拖拽源的id 
              }    
            }  
          
            //为目标对象添加事件监听 —— 删除拖动的源对象   
            target.ondragover= function(e){    
              e.preventDefault();  //阻止默认行为  
            }  
            target.ondrop= function(e){ //源对象松手释放在了目标对象中   
              //删除被拖动的源对象  
              var id = e.dataTransfer.getData('imgID');  
              var p = document.getElementById(id);   
              p.parentNode.removeChild(p);  //从父元素中删除子节点  
            }  
          
          </script> 
    
    1. 将本地图片拖放到页面中指定区域
      可将你的美图拖到网页中显示
      爆照前后效果:


      爆照前后

      主要代码:

    var content = document.querySelector('#content');
    
        document.addEventListener('dragover',function(e){
            e.preventDefault(); //阻止document的默认事件
        });
    
        document.addEventListener('drop',function(e){
            e.preventDefault(); //阻止document的默认事件(阻止照片在新窗口中打开)
        });
    
        content.addEventListener('dragover',function(e){
            e.preventDefault();
        })
    
        content.addEventListener('drop',function(e){
            var imgFs = e.dataTransfer.files[0];  //files存放了文件列表
            //console.log(imgFs);
            var fs = new FileReader();  //创建一个FileReader对象
            fs.readAsDataURL(imgFs);
            /*图片资源加载完成之后显示在content中*/
            fs.onload = function(){
                var img = new Image();
                img.src = fs.result;
                content.appendChild(img);
            }
        })
    

    小结

    对今天学习的知识点做个记录,欢迎大佬们指正~

    相关文章

      网友评论

        本文标题:拖放API中的drag和drop实战

        本文链接:https://www.haomeiwen.com/subject/nnrgkxtx.html