当前位置主页 > 资料库 > 前端教程 > HTML5教程 | HTML5元素拖放

HTML5教程 | HTML5元素拖放

2015-08-24

HTML5中你可以拖拽页面中指定的HTML元素。通过使用javascript事件监听,你可以决定元素在拖拽元素之后所发生的事情。

用于拖放的HTML元素中可以是以下两个角色:

  • Draggable(可拖动元素)
  • Drop target / drop zone(放置目标/放置区域)

可拖动的元素是指用户可以在页面中拖动并放置在其它地方的元素。它可以是一个或多个元素。

放置目标或放置区域是可拖动元素被放置的区域。

拖放事件

为了控制HTML元素的拖放,你需要执行3个步骤:

  • 选择一个HTML元素来拖动
  • 为拖动的HTML元素添加事件监听
  • 为放置HTML元素的区域添加事件监听

下图列出了拖放的事件和属性:

html5拖放事件示意图

首先,你需要在准备进行拖动的元素上设置draggable="true",使它可以被拖动。

接着你需要为拖动元素设置dragstartdragend事件监听。在这些事件中,你可以设置元素在开始拖动和结束拖动时发生的事情。

然后你需要在放置区域元素上添加事件监听,你可以监听的事件有:dragenterdragoverdragleavedrop

dragenter事件在你拖动元素到放置区域上方时被触发。这个事件只有在拖动元素从放置区域外部进入放置区域时被触发,这里通常是由鼠标的位置来决定的。

当拖动元素经过放置区域的时候,dragover事件会被触发。并会在拖动元素在放置区域内移动时持续触发。

如果你将拖动元素移到放置区域之外,dragleave事件将被触发。

如果你将拖动元素放置在放置区域之内,drop事件将被触发。

拖放事件的例子

下面是一个拖放事件的例子。你可以将HTML5的logo拖拽到放置区域中,看看右边的数据统计,还可以打开浏览器的控制台看看拖动元素被放下后的信息。

放置区域
dragstart:
dragend:

dragenter:
dragover:
dragleave:
drop:
元素拖放代码

下面让我们来看一下如何处理拖放事件。我们首先创建一个可以拖拽的图片元素。下面是它的HTML代码:

<img id="draggagle1" src="img/html5.png" draggable="true">                              
                            

然后我们需要一个放置的区域。这里使用一个<div>来制作。

<div id="droptarget1">放置区域</div>                              
                            

在完成上面的步骤之后,我们需要为它们添加事件监听。事件监听的代码如下:

<script>
    var draggable = document.getElementById("draggable1");

    draggable.addEventListener('dragstart', dragStart, false);
    draggable.addEventListener('dragend'  , dragEnd  , false);

    var droptarget = document.getElementById("droptarget1");

    droptarget.addEventListener('dragenter', dragEnter  , false);
    droptarget.addEventListener('dragover' , dragOver   , false);
    droptarget.addEventListener('dragleave', dragLeave  , false);
    droptarget.addEventListener('drop'     , drop       , false);


    /* Draggable event handlers */
    function dragStart(event) {
        event.dataTransfer.setData('text/html', "You dragged the image!");
    }

    function dragEnd(event) {
    }

    /* Drop target event handlers */
    function dragEnter(event) {
    }

    function dragOver(event) {
        event.preventDefault();
        return false;
    }

    function dragLeave(event) {
    }

    function drop(event) {
        var data = event.dataTransfer.getData('text/html');
        event.preventDefault();
        return false;
    }
</script>                              
                            

为了在拖放操作时实现数据交换,IE5引入了dataTransfer对象,它是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。因为它是事件对象的属性,所以只能在拖放事件的事件处理程序中访问dataTransfer对象。在事件处理程序中,可以使用这个对象的属性和方法来完善拖放功能。目前,HTML5规范草案也收入了dataTransfer对象。

dataTransfer对象有两个主要方法: getData()setData()getData()可以取得由setData()保存的值。setData()方法的第一个参数,也是getDAta()方法唯一的一个参数,是一个字符串,表示保存的数据类型,取值为”text”或“URL”,例如:

//设置和接收文本数据
event.dataTransfer.setDAta("text", "some text");
var text = event.dataTransfer.getData("text");

//设置和接收URL
event.dataTransfer.setData("URL", "HTML://www.htmleaf.com/");                              
                            

IE浏览器只定义了“text”和“URL”两种有效的数据类型,而HTML5则对此加以扩展,允许指定各种MIME类型。考虑到向后兼容,HTML5也支持“text”和“URL”,但这两种类型会被映射为“text/plain”和“text/uri-list”。

实际上,dataTransfer对象可以为每种MIME类型都保存一个值。换句话说,同时在这个对象中保存了一段文本和一个URL不会有任何问题。不过,保存在dataTransfer对象中的数据只能在drop事件处理程序中读取。如果在ondrop处理程序中没有读到数据,那就是dataTransfer对象已经被销毁,数据也丢失了。

在拖动文本框中的文本时,浏览器会调用setData()方法,将拖动的文本以“text”格式保存在dataTransfer对象中。类似地,在拖放链接或图像时,会调用setData()方法并保存URL。然后,在这些元素被拖放到放置目标时,就可以通过getData()读到这些数据。当然,作为开发人员,你也可以在dragstart事件处理程序中调用setData(),手工保存自己要传输的数据,以便将来使用。

将数据保存为文本和保存为URL是有区别的。如果将数据保存为文本格式,那么数据不会得到任何特殊处理。而如果将数据保存为URL,浏览器会将其当成网页中的链接。换句话说,如果你把它放置到另一个浏览器窗口中,浏览器就会打开该URL。

Firefox在其第5个版本之前不能正确地将“URL”和“text”映射为“text/uri-list”和“text/plain”。但是却能把“Text”映射为“text/plain”。为了更好地在跨浏览器的情况下从dataTransfer对象取得数据,最好在取得URL数据时检测两个值,而在取得文本数据时使用“text”。

var dataTransfer = event.dataTransfer;
//读取URL
var url = dataTransfer.getData("url") || dataTransfer.getData("text/uri-list");
//读取文本
var text = dataTransfer.getData("Text");                              
                            

注意,一定要把短数据类型放在前面,因为IE10及之前的版本仍然不支持扩展的MIME类型名,而它们在遇到无法识别的数据类型时,会抛出错误。

DataTransfer对象、effectsAllowed、dropEffect和setDragImage()

在上面我们已经介绍了一些关于DataTransfer对象的知识。DataTransfer能够在拖放元素的过程中给用户提供一些视觉效果。DataTransfer对象有两个属性和一个方法可以使用。它们是:

  • effectsAllowed
  • dropEffect
  • setDragImage()

你可以在dragstartdrop事件中访问DataTransfer对象。在下面的例子中,dragstart监听事件中在DataTransfer对象上设置了effectsAllowed属性。

function dragStart(event) {
    event.dataTransfer.effectsAllowed = "copy";
    event.dataTransfer.setData('text/html', "You dragged the image!");
    event.target.style.border = "1px solid #cccccc";
}                              
                            

effectsAllowed属性用于在元素拖放的过程中显示鼠标的样式。典型的例子是拖动一个元素经过放置区域时,鼠标会发生变化。effectsAllowed属性的可选值有:

  • none
  • copy
  • move
  • copyMove
  • link
  • linkMove
  • copyLink
  • all
  • uninitialized

dropEffect属性是拖动一个元素经过放置区域时,鼠标的样式。(似乎目前的浏览器还不支持这个属性)。它的可选值有:

  • none
  • copy
  • link
  • move

setDragImage(image, x, y)函数可以在用户拖动元素时显示指定的图片。默认情况下,在拖动元素的时候显示的是一个半透明的元素副本,可以通过这个函数来设置不同的图片。xy属性用于设置显示图片位置的偏移。

下面是一个使用dragStart()函数的示例代码:

function dragStart(event) {
    event.dataTransfer.effectAllowed  = "all";
    event.dataTransfer.dropEffect     = "copy";

    
    var dragImage = document.createElement('img');
    dragImage.src = dragImageUrl;
    dragImage.width = 75;
    event.dataTransfer.setDragImage(dragImage, 0, 0);
    
    event.dataTransfer.setData('text/html', "You dragged the image!");
    event.target.style.border = "1px solid #cccccc";
}                              
                            
拖动文件到浏览器中

我们还可以将操作系统中的文件拖拽到浏览器中,并通过HTML5 File API来查看文件的名称和内容。下面是一个示例代码:

var droptarget2 = document.getElementById("droptarget2");
droptarget2.addEventListener('drop', drop , false);


function drop(event) {

    // Files - array of dragged files.
    var files = event.dataTransfer.files;

    for(var i= 0; i < files.length; i++){
        var file = files[i];
        console.log("file: " + file.name);
    }

    event.preventDefault();
    return false;
}                              
                            

注意这里drop()方法中不是调用getData()函数,而是访问DataTransferfiles属性。files属性包含被拖动到浏览器中的文件列表。HTML5 File API将在后面的文章中详细介绍。

返回HTML5教程目录
Previous:
上一篇:HTML5教程 | HTML5信息API(Messaging API)
Next:
下一篇:HTML5教程 | HTML5 Web Workers
返回顶部