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的方法拖拽。我不会采用任何的库,而是用最原始的办法来实现,这将是最土鳖的方法,但是能体现拖动的原理。

      

  • 相关阅读:
    HDU-1225 Football Score
    HDU-3854 LOOPS
    HDU-3863 No Gambling
    poj-2096 Collecting Bugs
    HDU-4336 Card Collector
    HDU-4405 Aeroplane chess
    2010上交:最小面积子矩阵
    VijosP1443:银河英雄传说
    VijosP1250:分组背包
    Vijos1221:神秘的配方
  • 原文地址:https://www.cnblogs.com/yupeng/p/2404427.html
Copyright © 2011-2022 走看看