HTML5 File API 中的 FileReader.readAsText 如何工作?
我使用 HTML5 文件 API 编写了以下代码来检查上传的文件是否存在.
<input type="file" id="myfile"><button type="button" onclick="addDoc()">添加文档</button><p id="DisplayText"></p>
以下JavaScript代码已映射到它如下:
函数 addDoc() {var file=document.getElementById("myFile").files[0];//输入类型=文件var reader=new FileReader();reader.onload = 函数(e){}reader.readAsText(文件);var 错误 = reader.error;var texte=reader.result;document.getElementById("DisplayText").innerText=reader.result;/*<p id="显示文本>*/}
从本地系统浏览文件后,我尝试在单击 addDoc()
之前从文件夹中删除已浏览"的文档.单击按钮后,我仍然可以看到 Filereader.result
不为空,并且可以显示所有内容.
有人可以解释一下Filereader 的工作原理吗?FileReader 是不是文件一被浏览就被绑定了?
也可以用FileReader检查系统的Readonly属性是否类似于Java的File.canread()
?
有人可以就此提出建议吗?我有IE11来测试代码.
解决方案FileReader
load
事件异步设置 .result
值.要访问 .result
使用 load
或 loadend
事件.
当在 <input type="file">
Choose File
或 Browse...
UI 中选择了文件时,在本地文件系统删除文件不应影响 .files
调用返回的 FileList
处的 File
对象.请参阅 2.9.2.可传输对象,6.7.3 DataTransfer 接口一个>.
4.Blob 接口和二进制数据
每个 Blob
必须有一个内部 快照状态,其中必须初始设置为底层存储的状态(如果有)这种底层存储存在,并且必须通过结构化克隆
.snapshot state
的进一步规范定义可以在 文件
s.
2.9.8 猴子Blob 和 FileList 对象的补丁
这个猴子补丁将在适当的时候被删除.请参阅 w3c/FileAPI第 32 期.
Blob
对象是 可克隆对象
.
每个
Blob
对象的 [[Clone
]] 内部方法,给定 targetRealm 并忽略内存,必须运行以下步骤:如果这是
已关闭
,则抛出一个"DataCloneError"
DOMException
.
在targetRealm中返回一个新的this实例,对应于相同的基础数据.
FileList
对象是 可克隆对象.
每个 FileList
对象的 [[Clone]]
内部方法,给定targetRealm 和 memory,必须运行这些步骤:
让output成为targetRealm中的一个新的
FileList
对象.对于 this 中的每个 file,添加 ?
[StructuredClone][15](_file, targetRealm, memory_)
到文件
对象输出.
返回输出.
<小时>
在 webkit 和 firefox 浏览器中选择只读文件或文件夹
在 chrome 中,如果在本地文件系统中为文件设置了只读权限并且用户在 <input type="file">
元素处选择文件,则为 chromium,其中 FileReader
用于读取文件,在 FileReader
处抛出错误,由 FileReader
progress
事件生成.
如果将 Blob URL
设置为相同的文件对象,则 blob:
URL 将不会根据对 Blob 的请求返回只读文件网址
.
选择文件夹权限设置为只读的文件夹
铬、铬
在 chrome 中,设置了 webkitdirectory
属性并选择具有只读权限的文件夹 FileList
.length
of event 的 chromium.target.files
返回 0
;event.target.files.webkitGetAsEntry()
未被调用,未选择文件"
在 <input type="file">
处呈现代码> shadowDOM
.当文件夹被放置在 <input type="file">
或 droppable
属性设置的元素处时,目录 .name
和 <drop
event.dataTransfer
处显示只读文件夹的code>.path.
当用户在 <textarea>
元素处放置文件或文件夹时,其中没有附加 drop
事件 beforeunload
事件被调用并提示显示在 UI 上
你想离开这个网站吗?您所做的更改可能不会保存.<留下><离开>//<按钮>
火狐
在 Firefox 47.0b9 版中,allowdirs
属性设置在 元素中,用户单击
"选择文件夹.."
<input>
,父文件夹的.name
文件夹和.path
可在访问.then()
链接到 event.target.getFilesAndDirectories()
.递归迭代 Directory
条目时,不返回所选文件夹中包含的文件或文件夹;返回一个空字符串.
如果用户点击"Choose file..."
<input>
并且选择了一个没有设置只读权限的文件夹,当文件管理器的文件夹是单击后,将列出文件夹中的文件.
如果选择了设置了只读权限的文件夹,则会在 UI 显示时呈现 alert()
通知
无法读取<目录名>的内容没有权限
错误、安全问题
*nix 操作系统
当用户在 <textarea>
元素放置文件夹时,其中没有附加 drop
事件,用户文件系统中文件夹的完整路径 file:
协议已公开.文件夹中包含的文件的路径也没有设置为.value
;例如,
"file:///home/user/Documents/Document/"
当文件在 <textarea>
元素中被删除时,其中未附加 drop
事件,用户文件系统中文件的完整路径设置为 .value
of <textarea>
;也就是说,
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.txt"
如果在<textarea>
元素处选择并删除了多个文件,则所有完整文件路径都设置为,由换行符
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue1.txt"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue2.txt"..
XMLHttpRequest()
用于文件路径,错误记录在 console
NS_ERROR_DOM_BAD_URI:访问受限 URI 被拒绝
当设置为 <img>
元素的 .src
且 .crossOrigin
设置为 "anonymous"
img
error
事件处理程序被调用
调用 window.open()
并在第一个参数处设置完整路径
错误:从脚本访问 '"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.png"' 被拒绝
规格
4.10.5.1.18.文件上传状态(type=file
)
示例 16
由于历史原因,value
IDL 属性前缀带有字符串C:fakepath
"的文件名.一些旧版用户代理实际上包括完整路径(这是一个安全漏洞).因此,从 value
IDL 获取文件名向后兼容的属性是不平凡的.
4.10.5.4.常见的 <input>
元素 API
文件名
在获取时,它必须返回字符串C:fakepath",后跟 已选择文件
,如果有的话,或者如果列表为空,则为空字符串.在设置,如果新值是空字符串,它必须清空列表选定文件
;否则,它必须抛出InvalidStateError
"DOMException
.
注意:这种虚假路径"要求是历史的不幸事故.请参阅 文件上传 中的示例状态部分了解更多信息.
注意:由于选择文件
列表中的文件名中不允许出现路径组件
,因此fakepath
" 不会弄错的用于路径组件.
4.10.5.1.18.文件上传状态(type=file
)
路径组件
<块引用>当 <input>
元素的 type
属性在 File Upload
中时声明,本节中的规则适用.
<input>
元素 表示
选定文件
的列表,每个文件由文件名、文件类型和文件主体(文件的内容).
文件名不得包含 路径组件
,即使在 a用户选择了整个目录层次结构或多个文件来自不同目录的相同名称.路径组件,用于File Upload
状态的目的是文件名的那些部分由 U+005C REVERSE SOLIDUS 字符 () 字符分隔.
错误报告 https://bugzilla.mozilla.org/show_bug.cgi?id=1311823
<小时>在 <textarea> 放置文件在数据 URI 处
Neal Deakin 在错误报告中发表评论
<块引用>我认为提到的步骤是:
- 打开数据:text/html,
- 将文件从桌面拖到文本区域
我可以在 Linux 上重现这个,但不能在 Windows 或 Mac 上重现.
上面的预感是正确的;Linux 将数据包含为 url 和明文也是如此.
在 data:
prototcol data URI
在 firefox 和 chrome, chromium 中删除文件
data:text/html,<textarea></textarea>
火狐
文件或文件夹的完整路径名设置为
铬、铬
在 data URI
放置文件,在 chrome 中只有 textarea
元素,chromium 在地址栏用放置的文件路径替换 data URI
,并且在同一选项卡中加载拖放的文件,将 data URI
替换为拖放文件的内容.
plnkr http://plnkr.co/edit/ZfAGEAiyLLq8rGXD2ShE?p=preview
<小时>html
, javascript
重现上述问题
<!DOCTYPE html><html><头><风格>身体 {高度:400px;}文本区域 {宽度:95%;身高:继承;}</风格><脚本>window.onload = 函数(){var button = document.querySelector("#myfile + button");var input = document.getElementById("myfile");var display = document.getElementById("DisplayText");变种文字=空;函数 readFullPathToFileOnUserFileSystem(e) {var path = e.target.value;控制台.log(路径);var w = window.open(路径,_blank");var img = 新图像;img.crossOrigin = "匿名";img.onload = 函数() {document.body.appendChild(this);}img.onerror = 函数(错误){console.log("img 错误", err.message)}img.src = 路径;var request = new XMLHttpRequest();request.open("GET", path.trim(), true);request.onload = function() {console.log(this.responseText)}request.error = 函数(错误){控制台日志(错误消息)}请求.发送();}display.addEventListener("输入", readFullPathToFileOnUserFileSystem);input.addEventListener("改变", addDoc);input.addEventListener("进度", function(event) {console.log("进度", 事件)});button.addEventListener("点击", handleText)函数添加文档(事件){var mozResult = [];功能 mozReadDirectories(条目,路径){console.log("目录", 条目, 路径);return [].reduce.call(entry, function(promise, entry) {返回 promise.then(function() {console.log("入口", 入口);return Promise.resolve(entry.getFilesAndDirectories() || entry).then(函数(目录){console.log("dir getFilesAndDirectories", dir)返回目录})})}, Promise.resolve()).catch(函数(错误){控制台日志(错误,错误消息)}).then(函数(项目){console.log("items", items);var dir = items.filter(函数(文件夹){返回文件夹 instanceof 目录});var files = items.filter(function(file) {返回文件 instanceof File});如果(文件长度){console.log("文件:", 文件, 路径);mozResult = mozResult.concat.apply(mozResult, 文件);}如果(目录长度){console.log(dir, dir[0] instanceof Directory, dir[0]);返回 mozReadDirectories(dir, dir[0].path || path);} 别的 {如果(!dir.length){return Promise.resolve(mozResult).then(function(complete) {返回完成})}}}).catch(函数(错误){控制台日志(错误)})};console.log("文件", event.target.files);if ("getFilesAndDirectories" in event.target) {return (event.type === "drop" ? event.dataTransfer : event.target).getFilesAndDirectories().then(函数(目录){if (dir[0] instanceof 目录) {控制台日志(目录)返回 mozReadDirectories(dir, dir[0].path || 路径).then(函数(完成){console.log("完成:", 完成);event.target.value = null;});} 别的 {if (dir[0] instanceof File && dir[0].size > 0) {返回 Promise.resolve(dir).then(函数(完成){console.log("完成:", 完成);})} 别的 {if (dir[0].size == 0) {throw new Error("could not process '" + dir[0].name + "' directory" + " at drop event at firefox, upload folder at 'Choose folder...' input");}}}}).catch(函数(错误){控制台日志(错误)})}var reader = new FileReader();reader.onload = 函数(e){文本=读者.结果;console.log("FileReader.result", text);button.removeAttribute("禁用");}reader.onerror = 函数(错误){console.log(err, err.loaded, err.loaded === 0, 文件);button.removeAttribute("禁用");}reader.onprogress = function(e) {console.log(e, e.lengthComputable, e.loaded, e.total);}reader.readAsArrayBuffer(file);}函数句柄文本(){//用 `text` 做事:`addDoc` 中的 `reader.result`display.textContent = 文本;button.setAttribute("禁用", "禁用");//如果不需要或再次引用,将 `text` 设置为 `null`文本=空;}}</脚本></头><身体><input type="file" id="myfile" webkitdirectory 目录allowdirs><button type="button" disabled>添加文档</button><br><br><textarea id="DisplayText"></textarea></身体></html>
plnkr http://plnkr.co/edit/8Ovw3IlYKI8BYsLhzV88?p=preview
<小时>您可以使用附加到 #myfile
元素的 change
事件来处理用户的文件选择操作.
用 <textarea>
元素替换 <p>
元素以显示来自 .readAsText() 的
调用.load
事件的结果
要在 button
元素的 click
处显示 FileReader
的 .result
,请设置变量 text
到 reader.result
内 FileReader
的 load
事件中 click
事件的 button
将 #DisplayText
元素的 .textContent
设置为引用先前设置的变量 reader.result
.
<!DOCTYPE html><html><风格>身体 {高度:400px;}文本区域 {宽度:95%;身高:继承;}</风格><头><脚本>window.onload = 函数(){var button = document.querySelector("#myfile + button");var input = document.getElementById("myfile");var display = document.getElementById("DisplayText");变种文字=空;input.addEventListener("改变", addDoc);button.addEventListener("点击", handleText)函数添加文档(事件){var 文件 = this.files[0]var reader = new FileReader();reader.onload = 函数(e){文本=读者.结果;button.removeAttribute("禁用");}reader.onerror = 函数(错误){console.log(err, err.loaded, err.loaded === 0, 文件);button.removeAttribute("禁用");}reader.readAsText(event.target.files[0]);}函数句柄文本(){//用 `text` 做事:`addDoc` 中的 `reader.result`display.textContent = 文本;button.setAttribute("禁用", "禁用");//如果不需要或再次引用,将 `text` 设置为 `null`文本=空;}}</脚本></头><身体><input type="file" id="myfile" accept="text/*"><button type="button" disabled>添加文档</button><br><br><textarea id="DisplayText"></textarea></身体></html>
I wrote the following code to check whether the uploaded file exists or not using HTML5 file API.
<input type="file" id="myfile">
<button type="button" onclick="addDoc()">Add Document</button>
<p id="DisplayText"></p>
The following JavaScript code has been mapped to it is as follows:
function addDoc() {
var file=document.getElementById("myFile").files[0]; //for input type=file
var reader=new FileReader();
reader.onload = function(e) {}
reader.readAsText(file);
var error = reader.error;
var texte=reader.result;
document.getElementById("DisplayText").innerText=reader.result; /*<p id="DisplayText>*/
}
After browsing a file from local system I tried to delete the "browsed" document form the folder before clicking on addDoc()
. After clicking the button I could still see Filereader.result
is not null and could display all the content.
Can someone explain on how the Filereader works? Is it that the FileReader gets bound as soon as the file is browsed?
Also can we check whether the system Readonly Attribute with FileReader similar to Java File.canread()
?
Could someone suggest on this? I have IE11 to test the code.
解决方案FileReader
load
event sets the .result
value asynchronously. To access the .result
use load
or loadend
event.
When a file has been selected at <input type="file">
Choose File
or Browse...
UI, deleting file at local filesystem should not effect the File
object at FileList
returned by .files
call. See 2.9.2. Transferable objects, 6.7.3 The DataTransfer interface.
4. The Blob Interface and Binary Data
Each
Blob
must have an internal snapshot state, which must be initially set to the state of the underlying storage, if any such underlying storage exists, and must be preserved throughstructured clone
. Further normative definition ofsnapshot state
can be found forFile
s.
2.9.8 Monkey patch for Blob and FileList objects
This monkey patch will be removed in due course. See w3c/FileAPI issue 32.
Blob
objects arecloneable objects
.
Each
Blob
object's [[Clone
]] internal method, given targetRealm and ignoring memory, must run these steps:If this is
closed
, then throw a"DataCloneError"
DOMException
.Return a new instance of this in targetRealm, corresponding to the same underlying data.
FileList
objects are cloneable objects.Each
FileList
object's[[Clone]]
internal method, given targetRealm and memory, must run these steps:
Let output be a new
FileList
object in targetRealm.For each file in this, add ?
[StructuredClone][15](_file, targetRealm, memory_)
to the end of the list ofFile
objects of output.Return output.
Selecting read-only files or folders at webkit and firefox browsers
At chrome, chromium if read-only permission is set for file at local filesystem and user selects file at <input type="file">
element, where FileReader
is used to read file, an error is thrown at FileReader
, generated from FileReader
progress
event.
If a Blob URL
is set to the same file object, the blob:
URL will not return the the read-only file at request to the Blob URL
.
Selection of folder where folder permission is set to read-only
Chrome, chromium
At chrome, chromium where webkitdirectory
attribute is set and folder is selected with read-only permission FileList
.length
of event.target.files
returned 0
; event.target.files.webkitGetAsEntry()
is not called, "No file chosen"
is rendered at <input type="file">
shadowDOM
. When a folder is dropped at <input type="file">
or element where droppable
attribute set, the directory .name
and .path
of the read-only folder is displayed at drop
event.dataTransfer
.
When user drops file or folder at <textarea>
element, where no drop
event is attached beforeunload
event is called and a prompr is displayed at UI
Do you want to leave this site? Changes you made may not be saved. <Stay><Leave> // <buttons>
Firefox
At firefox version 47.0b9 with allowdirs
attribute is set at <input type="file">
element, where user clicks "Choose folder.."
<input>
, the folder .name
and .path
of the parent folder are accessible at .then()
chained to event.target.getFilesAndDirectories()
. The files or folders contained within the selected folder are not returned when recursively iterating Directory
entries; an an empty string is returned.
If user clicks "Choose file..."
<input>
and a folder is selected without read-only permission set, when the folder at file manager is clicked, the files in the folder are listed.
Where a folder is selected where read-only permission is set an alert()
notification is rendered at UI displaying
Could not read the contents of <directory name> Permission denied
Bug, security issue
*nix OS
When user drops folder at <textarea>
element, where no drop
event is attached, the full path to the folder at user filesystem file:
protocol is exposed. The paths to the files contained within the folder are not also set as .value
; e.g.,
"file:///home/user/Documents/Document/"
When a file is dropped at <textarea>
element, where not drop
event is attached, the full path to the file at user filesystem is set as .value
of <textarea>
; that is,
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.txt"
If multiple files are selected and dropped at <textarea>
element, all of the full file paths are set as .value
of <textarea>
, delineated by new line character
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue1.txt"
"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue2.txt"
..
Where an XMLHttpRequest()
is made for the file path and error is logged at console
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
When set as .src
of an <img>
element with .crossOrigin
set to "anonymous"
the img
error
event handler is called
At call to window.open()
with full path set at first parameter
Error: Access to '"file:///home/user/Documents/Document/MyFileFullPathDisplayedAtTextAreaValue.png"' from script denied
Specification
4.10.5.1.18. File Upload state (type=file
)
EXAMPLE 16
For historical reasons, the
value
IDL attribute prefixes the file name with the string "C:fakepath
". Some legacy user agents actually included the full path (which was a security vulnerability). As a result of this, obtaining the file name from thevalue
IDL attribute in a backwards-compatible way is non-trivial.
4.10.5.4. Common <input>
element APIs
filename
On getting, it must return the string "C:fakepath" followed by the name of the first file in the list of
selected files
, if any, or the empty string if the list is empty. On setting, if the new value is the empty string, it must empty the list ofselected files
; otherwise, it must throw an "InvalidStateError
"DOMException
.NOTE: This "fakepath" requirement is a sad accident of history. See the example in the File Upload state section for more information.
NOTE: Since
path components
are not permitted in file names in the list ofselected files
, the "fakepath
" cannot be mistaken for a path component.
4.10.5.1.18. File Upload state (type=file
)
Path components
When an
<input>
element’stype
attribute is in theFile Upload
state, the rules in this section apply.The
<input>
elementrepresents
a list ofselected files
, each file consisting of a file name, a file type, and a file body (the contents of the file).File names must not contain
path components
, even in the case that a user has selected an entire directory hierarchy or multiple files with the same name from different directories. Path components, for the purposes of theFile Upload
state, are those parts of file names that are separated by U+005C REVERSE SOLIDUS character () characters.
Bug report https://bugzilla.mozilla.org/show_bug.cgi?id=1311823
Dropping file at <textarea> at data URI
Following comment by Neal Deakin at bug report
I think the steps referred to are:
- Open data:text/html,
- Drag a file from the desktop to the textarea
I can reproduce this on Linux, but not on Windows or Mac.
The hunch above is correct; Linux is including the data as a url and plaintext as well.
dropped files at data:
prototcol data URI
at firefox, and chrome, chromium
data:text/html,<textarea></textarea>
Firefox
The full path name of file or folder set as .value
of <textarea>
.
Chrome, chromium
Dropping file at data URI
having only textarea
element at chrome, chromium replaces the data URI
with dropped file path at address bar, and loads the dropped file at the same tab, replacing the data URI
with the content of the dropped file.
plnkr http://plnkr.co/edit/ZfAGEAiyLLq8rGXD2ShE?p=preview
html
, javascript
to reproduce issue described above
<!DOCTYPE html>
<html>
<head>
<style>
body {
height: 400px;
}
textarea {
width: 95%;
height: inherit;
}
</style>
<script>
window.onload = function() {
var button = document.querySelector("#myfile + button");
var input = document.getElementById("myfile");
var display = document.getElementById("DisplayText");
var text = null;
function readFullPathToFileOnUserFileSystem(e) {
var path = e.target.value;
console.log(path);
var w = window.open(path, "_blank");
var img = new Image;
img.crossOrigin = "anonymous";
img.onload = function() {
document.body.appendChild(this);
}
img.onerror = function(err) {
console.log("img error", err.message)
}
img.src = path;
var request = new XMLHttpRequest();
request.open("GET", path.trim(), true);
request.onload = function() {
console.log(this.responseText)
}
request.error = function(err) {
console.log(err.message)
}
request.send();
}
display.addEventListener("input", readFullPathToFileOnUserFileSystem);
input.addEventListener("change", addDoc);
input.addEventListener("progress", function(event) {
console.log("progress", event)
});
button.addEventListener("click", handleText)
function addDoc(event) {
var mozResult = [];
function mozReadDirectories(entries, path) {
console.log("dir", entries, path);
return [].reduce.call(entries, function(promise, entry) {
return promise.then(function() {
console.log("entry", entry);
return Promise.resolve(entry.getFilesAndDirectories() || entry)
.then(function(dir) {
console.log("dir getFilesAndDirectories", dir)
return dir
})
})
}, Promise.resolve())
.catch(function(err) {
console.log(err, err.message)
})
.then(function(items) {
console.log("items", items);
var dir = items.filter(function(folder) {
return folder instanceof Directory
});
var files = items.filter(function(file) {
return file instanceof File
});
if (files.length) {
console.log("files:", files, path);
mozResult = mozResult.concat.apply(mozResult, files);
}
if (dir.length) {
console.log(dir, dir[0] instanceof Directory, dir[0]);
return mozReadDirectories(dir, dir[0].path || path);
} else {
if (!dir.length) {
return Promise.resolve(mozResult).then(function(complete) {
return complete
})
}
}
})
.catch(function(err) {
console.log(err)
})
};
console.log("files", event.target.files);
if ("getFilesAndDirectories" in event.target) {
return (event.type === "drop" ? event.dataTransfer : event.target)
.getFilesAndDirectories()
.then(function(dir) {
if (dir[0] instanceof Directory) {
console.log(dir)
return mozReadDirectories(dir, dir[0].path || path)
.then(function(complete) {
console.log("complete:", complete);
event.target.value = null;
});
} else {
if (dir[0] instanceof File && dir[0].size > 0) {
return Promise.resolve(dir)
.then(function(complete) {
console.log("complete:", complete);
})
} else {
if (dir[0].size == 0) {
throw new Error("could not process '" + dir[0].name + "' directory" + " at drop event at firefox, upload folders at 'Choose folder...' input");
}
}
}
}).catch(function(err) {
console.log(err)
})
}
var reader = new FileReader();
reader.onload = function(e) {
text = reader.result;
console.log("FileReader.result", text);
button.removeAttribute("disabled");
}
reader.onerror = function(err) {
console.log(err, err.loaded, err.loaded === 0, file);
button.removeAttribute("disabled");
}
reader.onprogress = function(e) {
console.log(e, e.lengthComputable, e.loaded, e.total);
}
reader.readAsArrayBuffer(file);
}
function handleText() {
// do stuff with `text`: `reader.result` from `addDoc`
display.textContent = text;
button.setAttribute("disabled", "disabled");
// set `text` to `null` if not needed or referenced again
text = null;
}
}
</script>
</head>
<body>
<input type="file" id="myfile" webkitdirectory directory allowdirs>
<button type="button" disabled>Add Document</button>
<br>
<br>
<textarea id="DisplayText"></textarea>
</body>
</html>
plnkr http://plnkr.co/edit/8Ovw3IlYKI8BYsLhzV88?p=preview
You can use change
event attached to #myfile
element to handle file selection action by user.
Substitute <textarea>
element for <p>
element to display result of load
event from .readAsText()
call.
To display .result
of FileReader
at click
at button
element, set variable text
to reader.result
within load
event of FileReader
at click
event at button
set .textContent
of #DisplayText
element to variable referencing previously set reader.result
.
<!DOCTYPE html>
<html>
<style>
body {
height: 400px;
}
textarea {
width:95%;
height: inherit;
}
</style>
<head>
<script>
window.onload = function() {
var button = document.querySelector("#myfile + button");
var input = document.getElementById("myfile");
var display = document.getElementById("DisplayText");
var text = null;
input.addEventListener("change", addDoc);
button.addEventListener("click", handleText)
function addDoc(event) {
var file = this.files[0]
var reader = new FileReader();
reader.onload = function(e) {
text = reader.result;
button.removeAttribute("disabled");
}
reader.onerror = function(err) {
console.log(err, err.loaded
, err.loaded === 0
, file);
button.removeAttribute("disabled");
}
reader.readAsText(event.target.files[0]);
}
function handleText() {
// do stuff with `text`: `reader.result` from `addDoc`
display.textContent = text;
button.setAttribute("disabled", "disabled");
// set `text` to `null` if not needed or referenced again
text = null;
}
}
</script>
</head>
<body>
<input type="file" id="myfile" accept="text/*">
<button type="button" disabled>Add Document</button><br><br>
<textarea id="DisplayText"></textarea>
</body>
</html>
相关文章