zoukankan      html  css  js  c++  java
  • 拖拽效果的实现原理分析

      一些网友给我反馈,希望我给下详细的demo,其实我觉得学习知识还是要自己动手,亲身实践下才体会深刻,顾没有提供可以使用的demo给大家直接下载下来看效果了,但是为了大家对我的期望,后面写的一些文章,如有必要,我都会给大家提供demo,供大家参考的。

      好了,进入正题,经常在网站上看到各种拖动的效果,很酷,如,百度新首页,接下来我来分析下拖动到底是什么实现的。

    一、html5现在已经提供支持拖动和拖放的API了,所以,支持html5的浏览器可以不必折腾了,直接使用吧。

      关于html5的拖拽api 请查看http://dev.w3.org/html5/spec/dnd.html 

     以下摘录一些 比较重要的对象和事件以及属性

    * 首先,要使元素能否能被拖拽,必须设置 draggable  = "true"  例如:<div  draggable =“true”>只有设置draggable才可以被拖拽</div>

    * 一个很很重要的接口 DataTransfer,它是拖拽对象用来传递的媒介,它包含以下属性和方法

    • dataTransfer.dropEffect [ = value ]:返回已选择的拖放效果,如果该操作效果与起初设置的effectAllowed效果不符,则拖拽操作失败。可以设置修改,包含这几个值:“none”, “copy”, “link” 和 “move”
    • dataTransfer.effectAllowed [ = value ]:返回允许执行的拖拽操作效果,可以设置修改,包含这些值:“none”, “copy”, “copyLink”, “copyMove”, “link”, “linkMove”, “move”, “all” 和 “uninitialized”
    • dataTransfer.types:返回在dragstart事件出发时为元素存储数据的格式,如果是外部文件的拖拽,则返回”files”
    • dataTransfer.clearData ( [ format ] ):删除指定格式的数据,如果未指定格式,则删除当前元素的所有携带数据
    • dataTransfer.setData(format, data):为元素添加指定数据
    • dataTransfer.getData(format):返回指定数据,如果数据不存在,则返回空字符串
    • dataTransfer.files:如果是拖拽文件,则返回正在拖拽的文件列表FileList
    • dataTransfer.setDragImage(element, x, y):制定拖拽元素时跟随鼠标移动的图片,x、y分别是相对于鼠标的坐标(据测试,Chrome暂不支持)
    • dataTransfer.addElement(element):添加一起跟随拖拽的元素,如果你想让某个元素跟随被拖拽元素一同被拖拽,则使用此方法(据测试,Chrome暂不支持)

    Drag & Drop 包括以下事件:

    • dragstart:要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素
    • dragenter:拖拽元素进入目标元素时触发,这个事件对象是目标元素
    • dragover:拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素
    • dragleave:拖拽某元素离开目标元素时触发,这个事件对象是目标元素
    • dragend:在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素
    • drop:将被拖拽元素放在目标元素内时触发,这个事件对象是目标元素

    注意:在ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用用document的ondragover事件把它直接干掉。

    下面我们来模拟一个购物车,将各种东西拖进到购物车里面去。

    首先看一个截图

    可以将商品往购物车里面拖动,当然你可以将购物车的东西拖出来。代码如下,里面都做了注释了,分析已经很详细了。

    <!DOCTYPE html >
    <html >
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
    <title>购物车DEMO</title>
    <style>
    .mod-buy
    {width:800px;margin:0 auto;}
    .mod-buy .inBox
    {width:600px; height:160px; line-height:1.5;border:1px solid #dfdfdf;margin-bottom:10px}
    .mod-buy .outBox
    {width:500px; height:150px; padding-left:20px;border:1px solid #dfdfdf;}
    .mod-buy .list
    { width:80px;float:left;height:30px;line-height:30px; margin:5px; border:2px dashed #444;
    background-color
    :#ddd; cursor:move;}
    .mod-buy .list:hover
    {border-color:#666; background-color:#888;}

    </style>
    </head>

    <body>
    <div class="mod-buy">
    <h3>购物车</h3>
    <div class="inBox"> </div>
    <h3>商品信息</h3>
    <div class="outBox">

    <div class="list" title="物品1" draggable="true">物品1</div>
    <div class="list" title="物品2" draggable="true">物品2</div>
    <div class="list" title="物品3" draggable="true">物品3</div>
    <div class="list" title="物品4" draggable="true">物品4</div>
    <div class="list" title="物品5" draggable="true">物品5</div>
    <div class="list" title="物品6" draggable="true">物品6</div>
    <div class="list" title="物品7" draggable="true">物品7</div>
    <div class="list" title="物品8" draggable="true">物品8</div>
    <div class="list" title="物品9" draggable="true">物品9</div>
    <div class="list" title="物品10" draggable="true">物品10</div>
    <div class="list" title="物品11" draggable="true">物品11</div>
    </div>
    </div>
    <script>

    (
    function(){

    var $ = function(selector,tag) {
    if (!selector) { return []; }
    var arrElement = [];
    if (document.querySelectorAll) {
    arrElement
    = document.querySelectorAll(selector);
    }
    else {
    var all = document.getElementsByTagName(tag);
    for (var i = 0,len = all.length; i<len; i++) {
    if (/^\./.test(selector)) {
    if (all[i].className === selector.replace(".", "")) {
    arrElement.push(all[i]);
    }
    }
    else if(/^/.test(selector)) {
    if (all[i].id === selector) {
    arrElement.push(all[i]);
    }
    }
    }
    }
    return arrElement;
    };

    var inBox = $(".inBox","div")[0],
    outBox
    = $(".outBox","div")[0],
    dragsEle
    = $("div",".list"),
    dragLen
    = dragsEle.length,
    eleDrag
    = null;
    //为拖拽的元素绑定事件
    for (var i=0; i<dragLen; i+=1) {
    //使拖拽的元素不能选定
    dragsEle[i].onselectstart = function() {
    return false;
    };
    //该元素开始拖动的时候
    dragsEle[i].ondragstart = function(ev) {
    ev.dataTransfer.effectAllowed
    = "move";
    ev.dataTransfer.setData(
    "text", ev.target.innerHTML);
    ev.dataTransfer.setDragImage(ev.target,
    10, 10);
    eleDrag
    = ev.target;
    return true;
    };
    //该对象结束拖动的时候
    dragsEle[i].ondragend = function(ev) {
    ev.dataTransfer.clearData(
    "text");
    eleDrag
    = null;
    return false
    };
    }
    //拖动该对象到目标对象上移动的时候
    inBox.ondragover = function(ev) {
    ev.preventDefault();
    return true;
    };
    //进入目标对象的时候
    inBox.ondragenter = function(ev) {
    return true;
    };
    //放开手的时候
    inBox.ondrop = function(ev) {
    if (eleDrag) {
    var tmp = eleDrag;
    eleDrag.parentNode.removeChild(eleDrag);
    this.appendChild(tmp);
    }
    return false;
    };
    outBox.ondragover
    = function(ev) {
    ev.preventDefault();
    return true;
    };

    outBox.ondragenter
    = function(ev) {

    return true;
    };
    outBox.ondrop
    = function(ev) {
    if (eleDrag) {
    var tmp = eleDrag;
    eleDrag.parentNode.removeChild(eleDrag);
    this.appendChild(tmp);
    }
    return false;
    };
    })();


    </script>
    </body>
    </html>

    下文再继续讲解不支持html5的方法拖拽。我不会采用任何的库,而是用最原始的办法来实现,这将是最土鳖的方法,但是能体现拖动的原理。

      

  • 相关阅读:
    PAT B1045 快速排序 (25 分)
    PAT B1042 字符统计 (20 分)
    PAT B1040 有几个PAT (25 分)
    PAT B1035 插入与归并 (25 分)
    PAT B1034 有理数四则运算 (20 分)
    PAT B1033 旧键盘打字 (20 分)
    HDU 1231 最大连续子序列
    HDU 1166 敌兵布阵
    HDU 1715 大菲波数
    HDU 1016 Prime Ring Problem
  • 原文地址:https://www.cnblogs.com/yupeng/p/2404427.html
Copyright © 2011-2022 走看看