Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
143023864X_HT5.pdf
Скачиваний:
8
Добавлен:
21.02.2016
Размер:
7.98 Mб
Скачать

CHAPTER 9 WORKING WITH DRAG-AND-DROP

<ul id="racers" dropzone=”copy s:text/plain s:text/html” ondrop=”handleDrop(event)”>

This provides a quick way of telling the browser that copy operations for elements that support either the plain text or HTML data format are allowed to drop on our list.

The dropzone is not supported by most major browser vendors at the time of writing, but support for it is likely forthcoming.

Handling Drag-and-Drop for Files

If you’ve ever wanted an easier way to add files to your web application, or you’ve wondered how some of the newest sites allow you to drag files directly into a page and upload them, the answer is the HTML5 File API. Although the size and status of the entire W3C File API is out of scope for this discussion, many browsers already support a subset of the standard, which allows files to be dragged into an application.

Note The W3C File API is documented online at www.w3.org/TR/FileAPI.

The File API contains functionality for asynchronously reading files in a web page, uploading them to servers while tracking process, and turning files into page elements. However, affiliated specifications such as drag-and-drop use a subset of the File API, and that is the area where we will focus our attention in this chapter.

Recall that we’ve already alluded to file drag-and-drop twice in this chapter. First, the dataTransfer object contains a property named files, which will contain a list of files attached to the drag, if appropriate. For example, if a user drags a file or set of files in from the desktop into your application’s web page, the browser will fire drag-and-drop events where the dataTransfer.files object has a value. Additionally, browsers that support the previously mentioned dropzone attribute allow files of specific MIME types to be valid drops on an element by using the f: MIME type prefix.

Note Currently, the Safari browser only supports drag-and-drop operations for files. Drags initiated inside a page will fire most drag-and-drop events, but drop events only occur if the type of drag is a file.

As usual, you cannot access the files during most drag-and-drop events, because they are protected for security reasons. Although some browsers might let you get access to the list of files during drag events, no browser will let you get access to the file data. In addition, the dragstart, drag, and dragend events that are fired at the drag source element are not triggered in a file drag-and-drop, as the source is the file system itself.

The file items in our file list support the following properties:

name: The full filename with extension

type: The MIME type of the file

size: The size of the file in bytes

lastModifiedDate: The timestamp for when the file contents were last modified

235

CHAPTER 9 WORKING WITH DRAG-AND-DROP

Let’s walk through a simple example of file drag-and-drop where we will show the characteristics of any file dropped onto our page, shown in Figure 9-5. This code is contained in the fileDrag.html example included with the book.

Figure 9-5. Demo page displaying the characteristics of dropped files

The HTML for our demo is actually quite simple (see Listing 9-13).

Listing 9-13. Markup for File Drop Demo

<body>

<div id="droptarget"> <div id="status"></div> </div>

</body>

We have only two elements in the page. A drop target where files will be dropped and a status display area.

As with our last example, we will register drag-and-drop event handlers during page load (see Listing 9-14).

236

CHAPTER 9 WORKING WITH DRAG-AND-DROP

Listing 9-14. Loading and Initialization Code for File Drop Demo

var droptarget;

//set the status text in our display function setStatus(text) {

document.getElementById("status").innerHTML = text;

}

//...

function loadDemo() {

droptarget = document.getElementById("droptarget"); droptarget.className = "validtarget";

droptarget.addEventListener("dragenter", handleDragEnter, false); droptarget.addEventListener("dragover", handleDragOver, false); droptarget.addEventListener("dragleave", handleDragLeave, false); droptarget.addEventListener("drop", handleDrop, false);

setStatus("Drag files into this area.");

}

window.addEventListener("load", loadDemo, false);

This time, the drop target receives all of the event handlers. Only a subset of handlers is needed, and we can ignore events that take place at the drag source.

When the user drags files into our drop target, we will display what we know about the drop candidates (see Listing 9-15).

Listing 9-15. File Drop Drag Enter Handler

// handle drag events in the drop target function handleDragEnter(evt) {

//if the browser supports accessing the file

//list during drag, we display the file count var files = evt.dataTransfer.files;

if (files)

setStatus("There are " + evt.dataTransfer.files.length + " files in this drag.");

else

setStatus("There are unknown items in this drag.");

droptarget.className = "highlighted";

evt.stopPropagation();

evt.preventDefault();

237

w

CHAPTER 9 WORKING WITH DRAG-AND-DROP

return false;

}

Although some browsers allow access to the dataTransfer files mid-drag, we will handle the case where that information is off-limits. When the count is known, we will display it in the status.

Handling dragover and dragleave events is straightforward (see Listing 9-16).

Listing 9-16. File drop dragover and dragleave Handlers

//preventing the default dragover behavior

//is necessary for successful drops function handleDragOver(evt) {

evt.stopPropagation();

evt.preventDefault();

return false;

}

// reset the text and status when drags leave function handleDragLeave(evt) {

setStatus("Drag files into this area.");

droptarget.className = "validtarget";

return false;

}

As always, we must cancel dragover events to allow drops to be handled by our own code rather than the browser’s default behavior, which is usually to display them inline. For a dragleave, we only set the status text and style to indicate that drops are no longer valid when the mouse leaves. The bulk of our work is done in the drop handler (see Listing 9-17).

Listing 9-17. File Drop Handler

// handle the drop of files function handleDrop(evt) {

// cancel the event to prevent viewing the file evt.preventDefault();

evt.stopPropagation();

var filelist = evt.dataTransfer.files;

var message = "There were " + filelist.length + " files dropped.";

// show a detail list for each file in the drag message += "<ol>";

[].forEach.call(filelist, function(file) { message += "<li>";

message += "<strong>" + file.name + "</strong> "; message += "(<em>" + file.type + "</em>) : ";

238