GWT拖放文件上传无效

时间:2013-07-18 15:44:29

标签: gwt dom file-upload drag-and-drop

所以我实现了一个非常简单的拖放文件上传小部件。基本上我的小部件是一个垂直面板,里面有几个标签和一个按钮。用户可以将文件拖动到垂直面板或单击按钮并浏览文件。

我的问题是,当我将文件拖到垂直面板时,每当我将项目拖动到标签或按钮占据的空间时,它就会触发DragLeaveEvent。我希望它知道该项目在垂直面板中,即使它位于标签或按钮的顶部。我确定我错过了一些简单的事情。我通过将这些dom处理程序添加到垂直面板来提供拖动功能:

addDomHandler(new DragEnterHandler() {
            @Override
            public void onDragEnter(DragEnterEvent event) {
                System.out.println("drag enter");
                highlight(true);
            }
        }, DragEnterEvent.getType());

addDomHandler(new DragLeaveHandler() {
            @Override
            public void onDragLeave(DragLeaveEvent event) {
                System.out.println("drag leave");
                highlight(false);
            }
        }, DragLeaveEvent.getType());

addDomHandler(new DragOverHandler() {
            @Override
            public void onDragOver(DragOverEvent event) {
            }
        }, DragOverEvent.getType());

addDomHandler(new DropHandler() {
            @Override
            public void onDrop(DropEvent event) {
                System.out.println("drop");
                // stop default behaviour
                event.preventDefault();
                event.stopPropagation();

                // starts the fetching, reading and callbacks
                if (fileUploadHandler != null) {
                    handleFiles(event.getDataTransfer(), fileUploadHandler);
                }
                highlight(false);
            }
        }, DropEvent.getType());    

3 个答案:

答案 0 :(得分:0)

检查事件目标是否是面板的子(或大孩子),或者在这种情况下,可能更确切地说事件目标是否是面板的元素:

if (verticalPanel.getElement().isOrHasChild(Node.as(event.getNativeEvent().getEventTarget()))) {
   // within the panel (possibly on a child)
}

if (verticalPanel.getElement() == Node.as(event.getNativeEvent().getEventTarget())) {
   // targetting exactly the panel (e.g. leaving the panel, not one of its children)
}

答案 1 :(得分:0)

通过大量的研究,我找到了唯一能找到的解决方案。我在dragover处理程序中将高亮显示设置为true,而不是拖动回车。

    panel.addDomHandler(new DragEnterHandler() {
        @Override
        public void onDragEnter(DragEnterEvent event) {
        }
    }, DragEnterEvent.getType());

    panel.addDomHandler(new DragLeaveHandler() {
        @Override
        public void onDragLeave(DragLeaveEvent event) {
            highlight(false);
        }
    }, DragLeaveEvent.getType());

    panel.addDomHandler(new DragOverHandler() {
        @Override
        public void onDragOver(DragOverEvent event) {
            highlight(true);
        }
    }, DragOverEvent.getType());

    panel.addDomHandler(new DropHandler() {
        @Override
        public void onDrop(DropEvent event) {
            // stop default behaviour
            event.preventDefault();
            event.stopPropagation();

            // starts the fetching, reading and callbacks
            handleFiles(event.getDataTransfer());
            highlight(false);
        }
    }, DropEvent.getType());

答案 2 :(得分:0)

我复制粘贴了您的代码,但还添加了一个:

RootPanel.get().addHandler(dropHandler, DropEvent.getType());

我的drophandler看起来像这样:

DropHandler dropHandler = new DropHandler() {

        @Override
        public void onDrop(DropEvent event) {
            handleFiles(event.getDataTransfer(), new FileUploadHandler() {
                @Override
                public TYPE specifyFileType() {
                    return TYPE.BINARY;
                }

                @Override
                public void handleFileContent(String fileName, String fileContent) {
                    // do stuff with filename and content
                }

                @Override
                public boolean checkFileName(String fileName) {
                    return true;
                }
            });
            event.preventDefault();
            event.stopPropagation();
        }
    };

和文件上传界面:

public interface FileUploadHandler {

    static public enum TYPE {
         TEXT, BINARY, DATAURL
    };

    // check the filename and extension and return true if you are happy with
    // proceeding
    // returnning false will prevent the file from being read
    boolean checkFileName(String fileName);

    // tell the method to use to read this file
    TYPE specifyFileType();

    // do your stuff here, eg upload to a server
    void handleFileContent(String fileName, String fileContent);
}

和句柄文件func:(请注意,您必须将类路径更改为FileUploadHandler接口)

// native method to make use of the HTML5 file API functionality
private final native void handleFiles(JavaScriptObject dataTransfer, FileUploadHandler fileUploadHandler) /*-{
    var files = dataTransfer.files;
    var i;
    var file;
    var reader = new FileReader();
    for (i = 0; i < files.length; i++) {
        file = files[i];
        if (fileUploadHandler.@<classpath_to>.FileUploadHandler::checkFileName(Ljava/lang/String;)(file.name)) {
            var type = fileUploadHandler.@<classpath_to>.FileUploadHandler::specifyFileType()();
            reader.onload = function(e) {
                fileUploadHandler.@<classpath_to>.FileUploadHandler::handleFileContent(Ljava/lang/String;Ljava/lang/String;)(file.name, e.target.result);
            }
            if (type == "TEXT") {
                reader.readAsText(file);
            } else if (type == "BINARY") {
                reader.readAsBinaryString(file);
            } else if (type == "DATAURL") {
                reader.readAsDataURL(file);
                // not supported
            } else if (type == "ARRAYBUFFER") {
                reader.readAsArrayBuffer(file);
            } else {
            }
        }
    }
}-*/;