zoukankan      html  css  js  c++  java
  • HTML5 drag api 的使用

    一、基础概念

    拖拽:Drag  释放:Drop

    1、拖拽指的是鼠标点击源对象后一直移动对象不松手,一但松手即释放了
    2、源对象:指的是我们鼠标点击的一个事物,这里可以是一张图片,一个DIV,一段文本等等
    目标对象:指的是我们拖动源对象后移动到一块区域,源对象可以进入这个区域,可以在这个区域上方悬停(未松手),可以释松手释放将源对象放置此处(已松手),也可以悬停后离开该区域。
     
    二、拖拽API相关函数
    被拖动的源对象可以触发的事件:
    1、ondragstart   源对象开始被拖动
    2、ondrag  源对象被拖动过程中(鼠标可能在移动也可能未移动)
    3、ondragend   源对象被拖动结束
     
    拖动对象进入到目标对象区域可以触发的事件
    1、ondragenter  目标对象被源对象拖动着进入
    2、ondragover  目标对象被源对象拖动着悬停在上方
    3、ondragleave  源对象拖动着离开了目标对象
    4、ondrop   源对象拖动着在目标对象上方释放/松手
     
    三、如何在拖动的源对象事件和目标对象事件之间传递数据
    HTML5为所有的拖动相关事件提供了一个新的属性
    e.dataTransfer  数据传递对象(用于在源对象事件和目标对象事件之间传递数据)
     
    源对象事件中保存数据:
    e.dataTransfer.setData(k, v)   k和v 都必须是string类型
     
    目标对象上的事件处理中读取数据:
    let v = emdataTransfer.getData( k )
     
    四:案例
     
    示例一:实现一个可以随着鼠标拖动而移动的效果
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <style>
            body{
                margin:0;
                position: relative;
            }
            img{
                position:absolute;
            }
        </style>
    </head>
    <body>
    <img id="p3" src="img/p3.png" alt=""/>
    <script>
        p3.οndragstart=function(e){
            console.log('事件源p开始拖动');
            offsetX= e.offsetX;
            offsetY= e.offsetY;
        }
        p3.οndrag=function(e){
            console.log('事件源p拖动中');
            var x= e.pageX;
            var y= e.pageY;
            console.log(x+'-'+y);
            //drag事件最后一刻,无法读取鼠标的坐标,pageX和pageY都变为0
            if(x==0 && y==0){
                return; //不处理拖动最后一刻X和Y都为0的情形
            }
            x-=offsetX;
            y-=offsetY;
     
            p3.style.left=x+'px';
            p3.style.top=y+'px';
        }
        p3.οndragend=function(){
            console.log('源对象p拖动结束');
        }
    </script>
    </body>
    </html>
    

    示例二:模拟电脑中 ”垃圾桶“的效果, 总共显示三个div方块,拖动着某个小方块到垃圾桶上方后,小方块从DOM树上删除

    提示:删除需要从DOM子节点中删除元素,需要阻止ondragover的默认行为,利用源对象和目标对象的数据传递记录小方块的ID值!!!

    注意:ondragover有一个默认行为,那就是当ondragover触发时,ondrop会失效,这个可能是浏览器的版本问题,以后浏览器不断更新可能会解决
    注意:浏览器默认允许我们拖拽图像、选中文本以及链接,让其它元素被拖动也是可以实现的,例如元素是一个DIV,默认是不能拖拽的,所以要给DIV的属性设置draggable="true"开启可拖拽状态即可
    如何阻止默认行为?
    ondragover= function(e){  //源对象在悬停在目标对象上时
      e.preventDefault();  //阻止默认行为,使得drop可以触发
        .....
    }
    ondrop= function(e){  //源对象松手释放在了目标对象中
        .....
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>小喵咪喂给大黄鱼</title>
        <style>
            body{
                text-align: center;
            }
    
            img{
                 80px;
                height: 80px;
                border-radius:100%;
            }
            #fish{
                 80px;
                height: 80px;
                margin-top: 200px;
                opacity: .2;
                background-color: yellow;
            }
            .cat{
               50px;
              height: 50px;
              background-color: red;
              margin: 10px;
            }
        </style>
    </head>
    <body>
     <div class="cat" id="cat1" draggable="true" > </div>
     <div class="cat" id="cat2" draggable="true" > </div>
     <div class="cat" id="cat3" draggable="true" > </div>
     <br>
     <div   id="fish"  ></div>
    </body>
    <script>
        //要想从数据库中删除猫咪,就需要猫咪的图片地址是后台传值过来的,然后循环遍历在页面中,当拖动删除的时候,删除掉数据库中的数据即可;然后刷新页面
        var  cat = document.getElementsByClassName('cat')//找到所有的猫咪
        for(var i = 0;i<cat.length;i++){
            var catSingle = cat[i];
            catSingle.ondragstart  = function(e){//循环遍历猫咪,当dragstart拖动开始的时候,setData设置他的id到e.dataTransfer中
                console.log('e.dataTransfer',e.dataTransfer)
                e.dataTransfer.setData('catId',this.id);
                console.log('e.dataTransfer',e.dataTransfer)
            }
        }
        fish.ondragenter = function(){//当如到鱼种时候,让鱼的透明度为1;
            console.log('已经拖入')
            fish.style.opacity ='1';
        }
        fish.ondragleave = function () {//拖动离开鱼的时候
            console.log('拖动离开');
            fish.style.opacity ='.2';
        }
        fish.ondragover = function (e) {//拖动悬浮在鱼上
            e.preventDefault()
        }
        fish.ondrop = function(e){//拖动放开时候;获取拖动开始时候设置的数据;然后从dom结构中移除;
            console.log('放开拖动')
            fish.style.opacity = '.2'
            var id = e.dataTransfer.getData('catId')
            console.log(id)
            var dragId = document.getElementById(id);
            dragId.parentNode.removeChild(dragId)
        }
    
    </script>
    </html>
    

      

    示例二:将本地图片图拖动放置到浏览器中指定区域显示

    相关知识点普及

    1、HTML5新增文件操作对象

    File  代表一个文件对象

    FileList  代表一个文件列表对象,类数组

    FileReader 用于从文件中读取数据

    FileWrite  用于像文件中写数据

    相关函数

    div.ondrop = function(e){
    
    var f = e.dataTransfer.files[0];      //找到拖放的文件
    
    var fr = new FileReader();        //创建文件读取器
    
    fr.readAsURLData(f);         //读取文件内容
    
    fr.onload = function(){       //读取完成
    
    img.src = fr.result;        //使用读取到的数据
    
    }
    
     }
    <!DOCTYPE html>
    <html>
    <head lang="en">
      <meta charset="UTF-8">
      <title></title>
      <style>
        #container {
          border: 1px solid #aaa;
          border-radius: 3px;
          padding: 10px;
          margin: 10px;
          min-height: 400px;
        }
      </style>
    </head>
    <body>
     
      <h3>拖动照片到下方方框区域</h3>
      <div id="container"></div>
     
      <script>
        //监听document的drop事件——取消其默认行为:在新窗口中打开图片
        document.ondragover = function(e){
          e.preventDefault(); //使得drop事件可以触发
        }
        document.ondrop = function(e){
          e.preventDefault(); //阻止在新窗口中打开图片,否则仍然会执行下载操作!!!
        }
     
        //监听div#container的drop事件,设法读取到释放的图片数据,显示出来
        container.ondragover = function(e){
          e.preventDefault();
        }
        container.ondrop = function(e){
          console.log('客户端拖动着一张图片释放了...')
          //当前的目标对象读取拖放源对象存储的数据
          //console.log(e.dataTransfer); //显示有问题
          //console.log(e.dataTransfer.files.length); //拖进来的图片的数量
          var f0 = e.dataTransfer.files[0];
          //console.log(f0); //文件对象 File
     
          //从文件对象中读取数据
          var fr = new FileReader();
          //fr.readAsText(f0); //从文件中读取文本字符串
          fr.readAsDataURL(f0); //从文件中读取URL数据
          fr.onload = function(){
            console.log('读取文件完成')
            console.log(fr.result);
            var img = new Image();
            img.src = fr.result; //URL数据
            container.appendChild(img);
          }
        }
     
      </script>
    </body>
    </html>

     五、拓展知识

    理解 e.clientX,e.clientY e.pageX e.pageY e.offsetX e.offsetY

    event.clientX、event.clientY

    鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性

    event.pageX、event.pageY

    类似于event.clientX、event.clientY,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这2个属性。

    event.offsetX、event.offsetY

    鼠标相对于事件源元素(srcElement)的X,Y坐标,只有IE事件有这2个属性,标准事件没有对应的属性。

    event.screenX、event.screenY

    鼠标相对于用户显示器屏幕左上角的X,Y坐标。标准事件和IE事件都定义了这2个属性

     

  • 相关阅读:
    Ubuntu下ATI显卡风扇转速调节脚本
    App_GlobalResources和LocalResources文件夹区别
    ubuntu下添加开机启动项
    UBUNTU安装PHP
    ubuntu apache2配置
    在ubuntu 上安装半透明玻璃窗口
    ASP.NET 页面:在此页面动态调用用户控件(.ASCX)
    Ubuntu 安装 LAMP 主机之后运行出现乱码
    Ubuntu下安装LMAP—菜鸟版
    Ubuntu 10.04风扇声音太大
  • 原文地址:https://www.cnblogs.com/liumingwang/p/14964351.html
Copyright © 2011-2022 走看看