前端浏览器支持的JS文件操作技术介绍
本文将介绍前端浏览器支持的JS文件操作技术。通过使用在 HTML5 中加入到 DOM 的 File API,使在 web 内容中让用户选择本地文件然后读取这些文件的内容成为可能。用户可以通过 HTML 中的 <input type="file"> 元素或者是通过拖拽来选择本地文件。
相关权威技术资料
在 web 应用程序中使用文件在 web 应用程序中使用文件 - Web API 接口参考 | MDN
带有 type="file" 的 <input> 元素允许用户可以从他们的设备中选择一个或多个文件。<input type="file"> - HTML(超文本标记语言) | MDN
FileReader 是HTML5新增的,其中FileReader API负责读取文件内容,FileSystem API负责本地文件系统的有限操作。FileReader - Web API 接口参考 | MDN
Node.js 中的文件系统,功能强大,Node.js是服务端网页编程技术,需要安装,在此不涉及,可参见其官网的相关部分File system | Node.js v19.2.0 Documentation
Node.js 提供额外的 API 用于支持在无浏览器环境中有用的功能,例如,创建 HTTP 服务器并访问文件系统,但不支持 DOM。
【特别提醒新手注意,ActiveXObject对象和FileSystemObject 对象仅在IE浏览器中实现文件的操作功能,微软已于2021年停止支持IE浏览器,属于淘汰技术,故不涉及】
显示图片方面的应用
HTML页面显示图片比较简单,html显示图片的基本方法:使用img标签,语法“<img src="图片文件地址" /> ”;
使用img标签插入图片
在HTML中,可以使用img 元素向网页中嵌入一幅图像。示例源码如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title> 测试</title>
</head>
<body>
<img src="./雪.png" width="250"/>
</body>
</html>
保存文件名为:图片.html,用浏览器打开显示效果如下:
这样的方法,图片不能更换,如何由用户打开对话框选定图片显示呢?这就需要JS文件操作技术了。
带有 type="file" 的 <input> 元素允许用户可以从他们的设备中选择文件。还可以用 accept 属性指定可接受的文件类型,它是一个以逗号间隔的文件扩展名和 MIME 类型列表。例如图像格式:accept=".png, .jpg, .jpeg"
示例源码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>选图显示</title>
</head>
<body>
<input type="file" id="file" accept=".png, .jpg, .jpeg" onchange="showPreview(this, 'portrait')" />
<img src="" id="portrait" style="width: 200px; display: block;" />
<script>
function showPreview(source, imgId) {
var file = source.files[0];
if(window.FileReader) {
var fr = new FileReader();
fr.onloadend = function(e) {
document.getElementById(imgId).src = e.target.result;
}
fr.readAsDataURL(file);
}
}
</script>
</body>
</html>
保存文件名为:选定显示图片.html,用浏览器打开显示效果如下:
文本文件方面的应用
例1、
例子中,创建了一个 file 类型的输入字段,它允许我们提供一个文件作为输入。然后指定一个 <pre> 标签显示读取的文件内容。被包围在 <pre> 标签中的文本通常会保留空格和换行符。本例用到了async 函数(异步函数、async function)详见async 函数 - JavaScript | MDN
源码如下:
<!DOCTYPE html>
<html>
<head>
<title>Read Text File Tutorial</title>
</head>
<body>
<input type="file" onchange="loadFile(this.files[0])">
<br>
<pre id="output"></pre>
<script>
async function loadFile(file) {
let text = await file.text();
document.getElementById('output').textContent = text;
}
</script>
</body>
</html>
保存文件名为:读入文本文件示例1.html,用浏览器打开显示效果如下:
例2、
例子中,使用file 类型的输入字段<input type="file" id="file" />来选择所需的文件。使用 <pre> 标签显示读取的文件内容,被包围在 <pre> 标签中的文本通常会保留空格和换行符。
输入字段由 getElementById 方法选择,该方法将在更改时触发该函数(无论何时选择文件)。我们创建对象 FileReader() 的新实例。当实例 reader.onload 被触发时,一个带有参数 progressEvent 的函数被调用,在控制台上将文件的全部内容打印为 console.log(this.result),也可在页面中将文件的内容输出document.getElementById('output').textContent = this.result。本例用到了FileReader。
源码如下:
<!DOCTYPE html>
<html>
<head>
<title>Read Text File Tutorial 2</title>
</head>
<body>
<input type="file" id="file" accept=".txt"/>
<br>
<pre id="output"></pre>
<script>
document.getElementById('file').onchange = function(){
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent){
console.log(this.result);
document.getElementById('output').textContent = this.result;
};
reader.readAsText(file);
};
</script>
</body>
</html>
保存文件名为:读入文本文件示例2.html,用浏览器打开显示效果类似上图。
例3、
修改上例的函数,实现逐行读取文件内容,使用 split() 来拆分 result 变量读取的内容并将其存储到数组 fileContentArray 变量中。然后使用 for 循环遍历 fileContentArray的每一行逐行处理文件内容。源码如下:
<!DOCTYPE html>
<html>
<head>
<title>Read Text File Tutorial 3</title>
</head>
<body>
<input type="file" name="file" id="file" accept=".txt"/>
<br>
<pre id="output"></pre>
<script>
document.getElementById('file').onchange = function(){
var file = this.files[0];
var reader = new FileReader();
var s="";
reader.onload = function(progressEvent){
var fileContentArray = this.result.split(/\r\n|\n/);
for(var line = 0; line < fileContentArray.length-1; line++){
console.log(fileContentArray[line]);
s = s + fileContentArray[line] + "\n";
}
document.getElementById('output').textContent = s;
};
reader.readAsText(file);
};
</script>
</body>
</html>
保存文件名为:读入文本文件示例3.html,用浏览器打开显示效果类似上图。
例3讲到的逐行读入看起来比例2麻烦,有何用处呢?看后面“可选定人员名单的随机点名例子”部分。
例4、
前面的例子将读出的文本放入<pre> 标签处,还可以放入文本框或多行文本框中。
在HTML中有两种方式的文本框
一是<input>标签的单行文本框,指定type的值为text,通过size属性指定显示字符的长度,value属性指定初始值,Maxlength属性指定文本框可以输入的最长长度,如:
<input type="text" value="" size="10" Maxlength="15">
二是<textarea>的多行文本框,内容可放在<textarea></textarea>标签对中,使用row、col指定大小,如:
<textarea cols="50" rows="10">内容内容内容</textarea>
下面给出将读入文件的内容放入多行文本框中的源码:
<!DOCTYPE html>
<html>
<head>
<title>读入入多行文本框</title>
</head>
<body>
读入文件<input type="file" id="file" accept=".txt"/>
<br>
<textarea id="output" cols="60" rows="20" readonly="readonly"></textarea>
<script>
document.getElementById('file').onchange =function(){
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent){
var fileContent = this.result;
document.getElementById('output').value = fileContent;
};
reader.readAsText(file);
};
</script>
</body>
</html>
保存文件名为:将文本文件读入多行文本框.html,用浏览器打开显示效果如下:
可选定人员名单的随机点名例子
例3讲到的逐行读入用处将在本例中体现。
下面给出的随机点名的例子,可从文本文件中读入人员名单,请准备人员名单文本文件,每人占一行,如:
能读入人员名单的随机点名,源码如下:
<!DOCTYPE html>
<html>
<head>
<title>随机点名网页</title>
<style>
#box {
width: 30%;
height: 200px;
background-color: rgb(233, 248, 214);
border: 1px solid rgb(130, 216, 18);
font-size: 40px;
font-weight: 600;
font-family: Arial, Helvetica, sans-serif;
line-height: 200px;
text-align: center;
margin: 25px auto;
border-radius: 10px;
}
span {
display: block;
width: 30%;
height: 44px;
line-height: 44px;
background-color: rgb(6, 158, 64);
border-radius: 10px;
color: #fff;
text-align: center;
margin: 0 auto;
font-size: 18px;
font-family: 华文细黑;
}
span:hover {
background-color: rgb(4, 190, 76);
}
</style>
</head>
<body>
人员名单文件<input type="file" id="file" accept=".txt"/>
<br>
<textarea id="output" cols="29" rows="5" readonly="readonly" ></textarea>
<div id="box">随机点名</div>
<span id="span">开始</span>
<script>
document.getElementById('file').onchange =function(){
var file = this.files[0];
var reader = new FileReader();
nameArr="";
reader.onload = function(progressEvent){
var fileContentArray = this.result.split(/\r\n|\n/);
console.log(fileContentArray);
for(var line = 0; line < fileContentArray.length-1; line++){
//console.log(fileContentArray[line]);
if(fileContentArray[line] != ""){
nameArr = nameArr + fileContentArray[line] + ",";
}
}
nameArr = nameArr.slice(0,nameArr.length-1); //删除最后一个字符这里是逗号
document.getElementById('output').value = nameArr;
//console.log(nameArr);
};
reader.readAsText(file);
};
var box = document.getElementById("box");
var span = document.getElementById("span");//获取元素
var state = 0;//定义状态,开始和结束
var t;
span.onclick = function () {
var arr = document.getElementById('output').value; //
if (arr =="" ){
alert("请先读入名单文件");
return;
}
arr = arr.split(","); //将字符串转为数组
console.log(arr);
if (state == 0) {
//如果是0即开始随机,变为1时结束,不是0时执行else
clearInterval(t);
t = setInterval(function () {
// console.log(1);
var sj = Math.round(Math.random() * (arr.length - 1));
//console.log(arr[sj]);
box.innerHTML = arr[sj];
}, 3)
span.innerHTML = "暂停"//更改按钮的内容
state=1;
}else{
state=0;
clearInterval(t);
span.innerHTML = "开始"
}
}
</script>
</body>
</html>
保存文件名为:可选定人员名单的随机点名.html,用浏览器打开显示效果如下:
OK!