高级功能使用拖放

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高级功能使用拖放相关的知识,希望对你有一定的参考价值。

html5 添加了对拖放(drag and drop)的支持。我们之前只能依靠jQuery 这样的javascript库才能处理这种操作。把拖放内置到浏览器的好处是它可以正确的集成到操作系统中,而且正如将要看到的,它能跨浏览器工作。

1. 创建来源项目

我们通过 draggable属性告诉浏览器文档里的哪些元素可以被拖动。这个值有三个允许的值:

它的默认值是auto,即把决定权交给浏览器,通常来说这就意味着所有元素默认都是可拖动的,我们必须显示设置draggable 属性为false 来禁止拖动。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>定义可拖放项目</title>
    <style>
        #src > * {float: left;}
        #target,#src > img {border: thin solid black;padding: 2px;margin: 4px;}
        #target {height: 81px;width: 81px;text-align: center;display: table;}
        #target > p {display: table-cell;vertical-align: middle;}
        #target > img {margin: 1px;}
    </style>
</head>
<body>
<div id="src">
    <img draggable="true" id="apple" src="../imgs/apple.png" alt="apple" />
    <img draggable="true" id="banana" src="../imgs/banana-small.png" alt="banana" />
    <img draggable="true" id="lemon" src="../imgs/lemon100.png" alt="lemon" />
    <div id="target">
        <p>Drop Here</p>
    </div>
</div>
<script>
    var src = document.getElementById("src");
    var target = document.getElementById("target");
</script>
</body>
</html>

此例里有三个img元素,每一个的draggable 的属性都被设为true。这里还创建了一个id为target的div元素,稍后将设置它用来接收我们拖动的img元素。从下图可以看到这个文档再来浏览器里的样子。

我们不需要再做任何设置就能拖动水果图像,但浏览器会提示我们不能把它们释放到任何地方。通常的做法是展示一个禁止进入的标准作为光标,如下图所示:

处理拖动事件

我们通过一系列事件来利用拖放功能

我们可以用这些事件在视觉上强调拖动操作,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用针对被拖动元素的事件</title>
    <style>
        #src > * {float: left;}
        #target,#src > img {border: thin solid black;padding: 2px;margin: 4px;}
        #target {height: 81px;width: 81px;text-align: center;display: table;}
        #target > p {display: table-cell;vertical-align: middle;}
        #target > img {margin: 1px;}
        img.dragged {background-color: lightgrey;}
    </style>
</head>
<body>
<div id="src">
    <img draggable="true" id="apple" src="../imgs/apple.png" alt="apple" />
    <img draggable="true" id="banana" src="../imgs/banana-small.png" alt="banana" />
    <img draggable="true" id="lemon" src="../imgs/lemon100.png" alt="lemon" />
    <div id="target">
        <p id="msg">Drop Here</p>
    </div>
</div>
<script>
    var src = document.getElementById("src");
    var target = document.getElementById("target");
    var msg = document.getElementById("msg");
    src.ondragstart = function(e){
        e.target.classList.add("dragged");
    }
    src.ondragend = function(e){
        e.target.classList.remove("dragged");
        msg.innerHTML = "Drop Here";
    }
    src.ondrag = function(e){
        msg.innerHTML = e.target.id;
    }
</script>
</body>
</html>

此例定义了一个新的CSS样式,它会被应用到属于dragged类的元素上。在dragstart事件触发时把拖动的元素添加到这个类中,在dragend事件触发时把它从类中移除。作为对drag事件的响应,这里把释放区里显示的文本设为被拖动元素的id值。在拖动操作过程中,drag事件每隔几毫秒就会触发以此,所以这不是最有效率的技巧,但它确实能演示这个事件。此例的显示效果如下:

2. 创建释放区

要让某个元素成为释放区,我们需要处理 dragenter和 dragover事件。它们是针对释放区的其中两个事件。

dragenter和 dragover 事件的默认行为是拒绝接受任何被拖放的项目,因此我们必须要做的最重要的事就是防止这种默认行为被执行。

PS:拖放功能的规范告诉我们还必须想要称为释放区的元素应用dropzone属性,而且此属性的值应当包含我们愿意接受的操作与数据类型细节。浏览器实际上不是这么实现拖放功能的。

修改前面例子的JavaScript代码如下:

<script>
    var src = document.getElementById("src");
    var target = document.getElementById("target");
    var msg = document.getElementById("msg");

    target.ondragenter = handleDrag;
    target.ondragover = handleDrag;

    function handleDrag(e){
        e.preventDefault();
    }

    src.ondragstart = function(e){
        e.target.classList.add("dragged");
    }
    src.ondragend = function(e){
        e.target.classList.remove("dragged");
        msg.innerHTML = "Drop Here";
    }
    src.ondrag = function(e){
        msg.innerHTML = e.target.id;
    }
</script>

添加这些代码后,我们就有了一个活动的释放区。当我们拖动一个项目到释放区元素上时,浏览器会提示如果我们放下时它就会被接受,如下图所示:

接受释放

我们通过处理drop事件来接收释放的元素,它会在某个项目被放到释放区元素上时触发。下面的例子展示了如何处理响应drop事件,具体的做法是使用一个全局变量作为被拖动元素和释放区之间的桥梁。 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>处理drop事件</title>
    <style>
        #src > * {float: left;}
        #target,#src > img {border: thin solid black;padding: 2px;margin: 4px;}
        #target {height: 81px;width: 81px;text-align: center;display: table;}
        #target > p {display: table-cell;vertical-align: middle;}
        #target > img {margin: 1px;}
        img.dragged {background-color: lightgrey;}
    </style>
</head>
<body>
<div id="src">
    <img draggable="true" id="apple" src="../imgs/apple.png" alt="apple" />
    <img draggable="true" id="banana" src="../imgs/banana-small.png" alt="banana" />
    <img draggable="true" id="lemon" src="../imgs/lemon100.png" alt="lemon" />
    <div id="target">
        <p id="msg">Drop Here</p>
    </div>
</div>
<script>
    var src = document.getElementById("src");
    var target = document.getElementById("target");
    var msg = document.getElementById("msg");

    var draggedID;

    target.ondragenter = handleDrag;
    target.ondragover = handleDrag;

    function handleDrag(e){
        e.preventDefault();
    }

    target.ondrop = function(e){
        var newElem = document.getElementById(draggedID).cloneNode(false);
        target.innerHTML = "";
        target.appendChild(newElem);
        e.preventDefault();
    }

    src.ondragstart = function(e){
        draggedID = e.target.id;
        e.target.classList.add("dragged");
    }
    src.ondragend = function(e){
        var elems = document.querySelectorAll(".dragged");
        for (var i=0;i<elems.length;i++){
            elems[i].classList.remove("dragged");
        }
    }
</script>
</body>
</html>

此例在dragstart事件触发时设置了变量draggedID 的值。这能够记录被拖动元素的id属性值。当drop事件触发时,用这个值克隆了被拖动的img元素,把它添加为释放区元素的一个子元素。其显示效果如下:

 

3. 使用DataTransfer对象

与拖放操作所触发的事件同时派发的对象是DragEvent,它派生于MouseEvent。DragEvent对象定义了Event与MouseEvent对象的所有功能,并额外增加了 dataTransfer 属性,用来返回用于传输数据到释放区的DataTransfer对象。

我们可以用DataTransfer对象从被拖动元素传输任意数据到释放区元素上。DataTransfer对象定义的属性和方法如下表所示:

在上个例子中,克隆了元素本身。但DataTransfer对象允许我们使用一种更为复杂的方式。我们能做的第一件事是用DataTransfer对象从被拖动元素传输数据到释放区,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用DataTransfer对象传输数据</title>
    <style>
        #src > * {float: left;}
        #target,#src > img {border: thin solid black;padding: 2px;margin: 4px;}
        #target {height: 81px;width: 81px;text-align: center;display: table;}
        #target > p {display: table-cell;vertical-align: middle;}
        #target > img {margin: 1px;}
        img.dragged {background-color:在两个片段之间拖放?

JavaScript笔试题(js高级代码片段)

Html5之高级-11 拖放API (拖放事件dataTransfer对象setDragImage方法)

使用 WindowManager.addView 添加动态视图

iPhone 4 iOS 5 高级ScrollView 技术:长按拖放按钮

套接字编程中的Java拖放问题