拖放(Drag 和 drop)是 HTML5 标准的组成部分,拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放

浏览器支持情况

  • Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。注释:在 Safari 5.1.2 中不支持拖放。

FileReader 介绍

  • FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据
  • 其中File对象可以是来自用户在一个 <input> 元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果
  • 详细 参考: MDN

下面是拖拽 读取一个文本文件例子(readAsText)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拖放-读取文本文件并显示</title>
<style>
#div1{text-align:center;margin:0 auto;width:500px;height:300px;line-height:300px;background-color: cadetblue;}
</style>
</head>
<body>
<div id="div1">
请将文件拖放到该区域
</div>
<script>
let div1 = document.getElementById('div1');
//拖着文件或者 html元素进入 一个区域
div1.addEventListener('dragenter',()=>{
div1.innerHTML = '释放鼠标';
},false);
//拖着文件或者 html元素移出 一个区域
div1.addEventListener('dragleave',()=>{
div1.innerHTML = '请将文件拖放到该区域';
},false);
//拖着文件进入后 悬停在元素上,只要悬停不离开该事件就会一直发生
//如果 dragover没有阻止 浏览器 默认行为,则drop不会发生
div1.addEventListener('dragover',(ev)=>{
console.log('鼠标悬停');
ev.preventDefault();
},false);
//松开鼠标
div1.addEventListener('drop',(ev)=>{
// console.log(ev.dataTransfer.files);
let oFile = ev.dataTransfer.files[0];
let reader = new FileReader();
//加载成功了
reader.onload = function(event) {
//下面3行代码一个意思---显示读取的文本文件的内容
console.log(event.target.result);
// console.log(this.result);
// console.log(reader.result);
};
//读取加载失败了
reader.onerror = function(event) {
alert('失败了');
};
reader.readAsText(oFile);//适合于读取文本文件
ev.preventDefault();//再次阻止浏览器的默认行为---打开文件
},false);
</script>
</body>
</html>

下面是拖拽 读取一张图片例子(readAsDataURL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>拖放-读取图片并显示</title>
<style>
#div1{text-align:center;margin:0 auto;width:500px;height:300px;line-height:300px;background-color: cadetblue;}
</style>
</head>
<body>
<div id="div1">
请将文件拖放到该区域
</div>
<img id="oImg01" src="" alt="tup" />
<script>
let div1 = document.getElementById('div1');
let oImg01 = document.getElementById('oImg01');
//拖着文件或者 html元素进入 一个区域
div1.addEventListener('dragenter',()=>{
div1.innerHTML = '释放鼠标';
},false);
//拖着文件或者 html元素移出 一个区域
div1.addEventListener('dragleave',()=>{
div1.innerHTML = '请将文件拖放到该区域';
},false);
//拖着文件进入后 悬停在元素上,只要悬停不离开该事件就会一直发生
//如果 dragover没有阻止 浏览器 默认行为,则drop不会发生
div1.addEventListener('dragover',(ev)=>{
console.log('鼠标悬停');
ev.preventDefault();
},false);
//松开鼠标
div1.addEventListener('drop',(ev)=>{
// console.log(ev.dataTransfer.files);
let oFile = ev.dataTransfer.files[0];
let reader = new FileReader();
//加载成功了
reader.onload = function(event) {
//读取一张图片,得到一个base64码,将其赋值给img元素的src属性,网页将显示读取的该图片
oImg01.src = event.target.result;
};
//读取加载失败了
reader.onerror = function(event) {
alert('失败了');
};
reader.readAsDataURL(oFile);//主要适合于读取图片(读取音频和视频太大了) 读出来是一个base64
ev.preventDefault();//再次阻止浏览器的默认行为---打开文件
},false);
</script>
</body>
</html>

下面是拖拽 读取为二进制文本(readAsBinaryString)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>拖放-二进制的文本形式</title>
    <style>
      #div1{text-align:center;margin:0 auto;width:500px;height:300px;line-height:300px;background-color: cadetblue;}
    </style>
  </head>
  <body>
    <div id="div1">
      请将文件拖放到该区域
    </div>
    <script>
      let div1 = document.getElementById('div1');
      //拖着文件或者  html元素进入  一个区域
      div1.addEventListener('dragenter',()=>{
        div1.innerHTML = '释放鼠标';
      },false);
      //拖着文件或者 html元素移出  一个区域
      div1.addEventListener('dragleave',()=>{
        div1.innerHTML = '请将文件拖放到该区域';
      },false);
      //拖着文件进入后  悬停在元素上,只要悬停不离开该事件就会一直发生 
      //如果 dragover没有阻止 浏览器 默认行为,则drop不会发生
      div1.addEventListener('dragover',(ev)=>{
        console.log('鼠标悬停');
        ev.preventDefault();
      },false);
      //松开鼠标
      div1.addEventListener('drop',(ev)=>{
        // console.log(ev.dataTransfer.files);
        let oFile = ev.dataTransfer.files[0];
        let reader = new FileReader();
        //加载成功了
        reader.onload = function(event) {
          console.log(this.result);
        };
        //读取加载失败了
        reader.onerror = function(event) {
          alert('失败了');
        };
        reader.readAsBinaryString(oFile);//读为  二进制的文本形式数据   
        ev.preventDefault();//再次阻止浏览器的默认行为---打开文件
      },false);
    </script>
  </body>
</html>

小结

  • reader.readAsText(oFile) 读为 文本 适合于文本文件
  • reader.readAsDataUrl(oFile) 读为 base64 (可做图片上传预览) 适合于图片文件
  • reader.readAsArrayBuffer(oFile) 读为 原始二进制数据 适合于编辑(不实用)
  • reader.readAsBinaryString(oFile) 读为 二进制的文本形式数据 适合于上传

扩展知识

  • base64 的编码原理