html5拖拽ondragover为啥要阻止默认行为

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了html5拖拽ondragover为啥要阻止默认行为相关的知识,希望对你有一定的参考价值。

你可以试试看,有两种做法,一种是直不写dragover的事件,另一种是写,但里面不执行影响内存的事件。
我测试了下,是没有影响的,
参考技术A 水电费可接受的你发你的身份

H5 拖拽读取文件和文件夹

1)拖拽方面的重点是:ondragover 事件 和 ondrop 事件

ondragover 是必须的,ondragover 事件里禁用掉 html 的默认事件,否则 ondrop 事件将无效(直接捕捉不到ondrop事件了)

dropzone.addEventListener("dragover", function(event) {
    event.preventDefault();
}, false);

2)读取目录用到的 webApi 主要有: FileSystemFileEntryFileSystemDirectoryEntryFileSystemDirectoryReader

3)详情说明及示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>H5 拖拽读取文件和文件夹</title>
<style type="text/css">
    #dropzone {
      text-align: center;
      width: 300px;
      height: 100px;
      margin: 10px;
      padding: 10px;
      border: 4px dashed red;
      border-radius: 10px;
    }
    #boxtitle {
      display: table-cell;
      vertical-align: middle;
      text-align: center;
      color: black;
      font: bold 2em "Arial", sans-serif;
      width: 300px;
      height: 100px;
    }
    body {
      font: 14px "Arial", sans-serif;
    }
</style>
</head>
<body>
<p>
    Drag files and/or directories to the box below!
</p>
<div id="dropzone">
    <div id="boxtitle">
        Drop Files Here
    </div>
</div>
<h2>Directory tree:</h2>
<ul id="listing">
</ul>

<script type="text/javascript">
    let dropzone = document.getElementById("dropzone");
    let listing  = document.getElementById("listing");

    /**
     * 读取文件
     * @param  item         FileSystemDirectoryEntry 对象实例(目录实体)
     * @param  container     显示容器
     * @return void
     */
    function scanFiles(item, container) {
        let elem       = document.createElement("li");
        elem.innerHTML = item.name;
        container.appendChild(elem);

        // 如果是目录,则递归读取
        if (item.isDirectory) {
            // 使用目录实体来创建 FileSystemDirectoryReader 实例
            let directoryReader    = item.createReader();
            let directoryContainer = document.createElement("ul");
            container.appendChild(directoryContainer);

            // 上面只是创建了 reader 实例,现在使用 reader 实例来读取 目录实体(读取目录内容)
            directoryReader.readEntries(function(entries) {
                // 循环目录内容
                entries.forEach(function(entry) {
                    // 处理内容(递归)
                    scanFiles(entry, directoryContainer);
              });
            });
        }
    }

    // 此事件是必须的,且要阻止默认事件
    dropzone.addEventListener("dragover", function(event) {
        event.preventDefault();
    }, false);

    // 拖拽结束时触发
    dropzone.addEventListener("drop", function(event) {
        // 拖拽(转移)的对象列表
        let items = event.dataTransfer.items;
        event.preventDefault();
        listing.innerHTML = "";
        for (let i=0; i<items.length; i++) {
            // file 对象(按实例拖拽的内容)转换成 FileSystemFileEntry 对象 或 FileSystemDirectoryEntry 对象
            let item = items[i].webkitGetAsEntry();
            if (item) {
                // 读取文件
                scanFiles(item, listing);
            }
        }
    }, false);
    </script>
</body>
</html>

 

4)用到的其他 Api:

https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/dataTransfer

https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem

https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry

 

5)官方原版示例:

https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryReader/readEntries

 

以上是关于html5拖拽ondragover为啥要阻止默认行为的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用html5的拖拽功能,在火狐中总会弹出一个新面页?

H5 拖拽读取文件和文件夹

html5的拖拽dragAPI(如果看了API不懂,看看那三个案例就会恍然大悟)

html新特性——拖拽(drag和drop)

h5拖放

html5移动端阻止滚动问题。