10

我正在尝试获得与 dropbox 类似的拖放功能。我想尽可能使用基本的网络组件/编码来实现这一点。HTML 或 HTML5 最好。这是为了原型,所以越快越好。这是我想要实现的目标:

1) 用户应该能够将文件从他们的计算机拖放到网页上的任何位置。2) 当一个项目被拖到它上面时,网页本身应该显示一些指示符(即:突出显示或颜色叠加)。

我已经看到了几个示例的代码片段,但它们都仅限于将已经在屏幕上的容器放入其他容器中,而不是将太多文件放入网页中。

删除的文件不需要上传到任何地方,因为这将是一个演示。

任何人都有一些可以让我前进的代码片段。

4

2 回答 2

15

The basic idea is this:

  • Keep the drop zone hidden by default.
  • Attach a handler to the html element that will show the zone when something is being dragged over the page.
  • When the zone is visible, tap into its events to handle drag and drop.
  • When the mouse leaves the zone, hide it.

Here is the code that worked for me: https://jsfiddle.net/oL2akhtz/.


This part of HTML5 spec is a little bit strange. The most important things to keep in mind are these:

  • There are four interesting events: dragenter fires when we drag something and enter the bounds of an element; dragover fires every few ms while we are dragging something over the element; dragleave is the opposite of dragenter; drop fires when something is actually dropped.
  • You must listen to both dragenter and dragover on any element that is a valid drop target. That is, the element is turned into a valid drop target by listening to those events and cancelling their default actions. In our case this applies to the drop-zone overlay.

Now I’ll try to explain my code.

  1. First we add a listener that handles dragenter for the whole page. It just shows the overlay (and there is no need to prevent the default action as we actually do not intend to drop anything on the page, we will be dropping only on the overlay).
  2. Setup handlers for dragenter and dragover for the overlay. They prevent the default actions (which are to disallow dropping there) and also set dropEffect to give the user some nice feedback (although this seems to do nothing right now in modern browsers). This is a good place to test whether the item being dragged is valid.
  3. If the mouse leaves the drop zone (which is the same as the whole window, since the div covers everything) we hide it.
  4. Setup the actual drop handler.

That’s it, pretty straightforward. Here is what happens when someone drops a file:

  1. dragenter for the html element fires. It shows the dropzone.
  2. Since the mouse is now over the dropzone, dragleave for the html element fires, but we ignore it.
  3. dragenter for the dropzone fires and then dragover keeps firing. We just jeep saying that, yes, this is a valid drop target.
  4. Either drop fires, in which case we hide the dropzone and process the file, or dragleave for the dropzone fires in which case we just hide it.
于 2015-11-25T12:51:16.183 回答
0

这是最终的工作

首先是 HTML 代码:

<body id="drop1" align=center>
<DIV id="content" >Drop files here

<h1 align=center>A File Preview Demo</h1>

    <DIV id="status">Drag the files from a folder to a selected area ...</DIV>
    <DIV id="drop2">Drop files here.</DIV>
    <DIV id="list"></DIV>
    <DIV id="list2"></DIV>
</DIV>
</body>

接下来是CSS代码:

html,body{
    height: 96%;
    }

#drop1 {
    height: 100%;
    width: 97%;
    border: 2px solid blue;
    margin: 0px;
    padding: 10px;
    background-color: yellow;
    overflow:hidden; 
}
#drop2 {
    height: 30%;
    width: 30%;
    border: 1px solid red;
    margin: 10px;
    padding: 10px;
}
#content
{
    height: 100%;
    width: 100%;
}
.hoverClass {
    background-color: blue;
}
.dropClass {
    background-color: green;
}

最后的JS代码:

if (window.FileReader) {
    var drop;
    var drop2;
    var fileNumber = 0;
    addEventHandler(window, 'load', function () {
        var status = document.getElementById('status');
        drop = document.getElementById('drop1');
        drop2 = document.getElementById('drop2');
        var list = document.getElementById('list');
        var list2 = document.getElementById('list2');


        function cancel(e) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            return false;
        }

        // Tells the browser that we *can* drop on this target
        addEventHandler(drop, 'dragover', function (e) {
            e = e || window.event; // get window.event if e argument missing (in IE) 
            if (e.preventDefault) {
                e.preventDefault();
            }
            fileNumber = fileNumber + 1;
            status.innerHTML = fileNumber;
            $("#drop1").css("background-color", '#AA0000');

            return false;
        });
        // Tells the browser that we *can* drop on this target
        addEventHandler(drop, 'dragleave', function (e) {
            e = e || window.event; // get window.event if e argument missing (in IE) 
            if (e.preventDefault) {
                e.preventDefault();
            }
            fileNumber = fileNumber + 1;
            status.innerHTML = fileNumber;
            $("#drop1").css("background-color", '#FF0000');

            return false;
        });

        addEventHandler(drop, 'dragenter', cancel);
        addEventHandler(drop2, 'dragover', cancel);
        addEventHandler(drop2, 'dragenter', cancel);


        addEventHandler(drop, 'drop', function (e) {
            e = e || window.event; // get window.event if e argument missing (in IE)   
            if (e.preventDefault) {
                e.preventDefault();
            } // stops the browser from redirecting off to the image.

            var dt = e.dataTransfer;
            var files = dt.files;
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                var reader = new FileReader();

                //attach event handlers here...  
                reader.readAsDataURL(file);

                addEventHandler(reader, 'loadend', function (e, file) {
                    var bin = this.result;
                    var newFile = document.createElement('div');
                    newFile.innerHTML = 'Loaded : ' + file.name + ' size ' + file.size + ' B';
                    list.appendChild(newFile);
                    var fileNumber = list.getElementsByTagName('div').length;
                    status.innerHTML = fileNumber < files.length ? 'Loaded 100% of file ' + fileNumber + ' of ' + files.length + '...' : 'Done loading. processed ' + fileNumber + ' files.';

                    var img = document.createElement("img");
                    img.file = file;
                    img.src = bin;
                    list.appendChild(img);
                }.bindToEventHandler(file));
            }
            return false;
        });

        addEventHandler(drop2, 'drop', function (e) {
            e = e || window.event; // get window.event if e argument missing (in IE)   
            if (e.preventDefault) {
                e.preventDefault();
            } // stops the browser from redirecting off to the image.

            var dt = e.dataTransfer;
            var files = dt.files;
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                var reader = new FileReader();

                //attach event handlers here...  
                reader.readAsDataURL(file);

                addEventHandler(reader, 'loadend', function (e, file) {
                    var bin = this.result;
                    var newFile = document.createElement('div');
                    newFile.innerHTML = 'Loaded : ' + file.name + ' size ' + file.size + ' B';
                    list.appendChild(newFile);
                    var fileNumber = list.getElementsByTagName('div').length;
                    status.innerHTML = fileNumber < files.length ? 'Loaded2 100% of file ' + fileNumber + ' of ' + files.length + '...' : 'Done loading. processed ' + fileNumber + ' files.';

                    var img = document.createElement("img");
                    img.file = file;
                    img.src = bin;
                    list.appendChild(img);
                }.bindToEventHandler(file));
            }
            return true;
        });

        Function.prototype.bindToEventHandler = function bindToEventHandler() {
            var handler = this;
            var boundParameters = Array.prototype.slice.call(arguments);
            //create closure
            return function (e) {
                e = e || window.event; // get window.event if e argument missing (in IE)   
                boundParameters.unshift(e);
                handler.apply(this, boundParameters);
            }
        };
    });
} else {
    document.getElementById('status').innerHTML = 'Your browser does not support the HTML5 FileReader.';
}

function addFile(evt) {
    e = e || window.event; // get window.event if e argument missing (in IE)   
    if (e.preventDefault) {
        e.preventDefault();
    } // stops the browser from redirecting off to the image.

    var dt = e.dataTransfer;
    var files = dt.files;
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var reader = new FileReader();

        //attach event handlers here...  
        reader.readAsDataURL(file);

        addEventHandler(reader, 'loadend', function (e, file) {
            var bin = this.result;
            var newFile = document.createElement('div');
            newFile.innerHTML = 'Loaded : ' + file.name + ' size ' + file.size + ' B';
            list.appendChild(newFile);
            var fileNumber = list.getElementsByTagName('div').length;
            status.innerHTML = fileNumber < files.length ? 'Loaded2 100% of file ' + fileNumber + ' of ' + files.length + '...' : 'Done loading. processed ' + fileNumber + ' files.';

            var img = document.createElement("img");
            img.file = file;
            img.src = bin;
            list.appendChild(img);
        }.bindToEventHandler(file));
    }
    return false;
}

//seperate event
function addEventHandler(obj, evt, handler) {
    if (obj.addEventListener) {
        // W3C method
        obj.addEventListener(evt, handler, false);
    } else if (obj.attachEvent) {
        // IE method.
        obj.attachEvent('on' + evt, handler);
    } else {
        // Old school method.
        obj['on' + evt] = handler;
    }
}

http://jsfiddle.net/JtJ5N/79/

快乐编码!

于 2013-11-07T20:41:46.897 回答