我尝试在HTML和Javascript中进行简单的文件上传。
我设置它的方式是让<input type="file" id="file-upload-input"/>
订阅loadFile
事件的onChange
函数。 (因为它看起来很糟糕,我有input
隐形。)
然后我有一个<button/>
函数handleBrowseClick
订阅了它的onclick
事件。
上述两个控件似乎都运行正常:当我点击<button/>
时,会调用handleBrowseClick
,点击我的<input type="file">
,导致文件对话框打开。但是,一旦我选择了一个文件并按下&#34;打开&#34;在对话框中(触发<input type="file">
的{{1}}事件,从而调用我的onChange
函数。
正如您在Javascript中看到的那样,此时尝试通过获取loadFile
,访问其<input type="file">
属性并尝试获取该数组的第一个元素来读取该文件,以便我可以用files
读取它(它工作正常)。
但是,无论我选择哪个文件,FileReader
数组始终为空(因此我的files
打印出alert
)!在经过大量调试并缩小问题范围之后,我发现在"# Files Selected: 0"
中,如果我删除稍微修改HTML主体的调试代码,那么文件上传突然完美无缺! (handleBrowseClick()
打印出alert
。)
所以这就是我的问题:为什么会有一条
阻止我的文件上传工作?
"# Files Selected: 1"
&#13;
function handleBrowseClick()
{
document.getElementById("upload-file-input").click();
// if I comment out this line, then the file upload works
document.body.innerHTML += "<br/>Browsing...";
}
function loadFile()
{
var elem = document.getElementById("upload-file-input");
var files = elem.files;
alert("# Files Selected: " + files.length);
var file = files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function()
{
// do stuff with reader.result
// example:
document.getElementById("file-content").innerHTML = reader.result;
};
reader.readAsText(file);
}
&#13;
答案 0 :(得分:1)
使用innerHTML +=
解释HTML,它不仅会添加一些文本,而是删除所有内容并重新创建整个HTML。见https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML:
因此,建议您在使用innerHTML时不要使用 插入纯文本;相反,使用node.textContent。事实并非如此 将传递的内容解释为HTML,而是将其作为原始内容插入 文本。
因此,在您调用之前,input
元素与之后的元素不同。您可以在下面的jsfiddle中看到,比较调用之前和之后的节点,当您使用innerHTML +=
时,您将看到它不是相同的元素,即使HTML是相同的。
http://jsfiddle.net/6nja0v6b/1/
修改
原始答案中的引用可能导致混淆,而它描述了innerHTML的作用,上下文不是问题之一。可以在此处找到更精确的描述:https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML。特别是:
元素。 innerHTML [= value]
返回表示元素的HTML或XML片段 内容。
可以设置,用解析的节点替换元素的内容 来自给定的字符串。
和
在设置时,必须运行以下步骤:
让片段成为调用片段解析算法的结果 将新值作为标记,将上下文对象作为上下文 元件。将所有内容替换为上下文对象中的片段。
通过在eventListener
上添加node
,然后调用innerHTML
在该节点上插入完全相同的HTML,可以非常简单地说明这一点。虽然文档看起来相同,但行为不一致,因为innerHTML
重新创建节点结构,innerHTML
调用之前的节点与之后的节点不同。请参阅代码段:
var container = document.querySelector("#container");
var testElem = document.querySelector("#testElement");
var replaceBtn = document.querySelector("#replaceHtml");
var compareBtn = document.querySelector("#compare");
//We add the listener on original testElem
testElement.addEventListener('click', function(e) {
alert("eventListener is working");
})
//After using innerHTML, event listener won't work and compare will be false
replaceBtn.onclick = function() {
//This doesn't change the HTML, but replaces the node
container.innerHTML = container.innerHTML;
}
//Use this to compare original testElement to new one. After innerHTML is used, it's not the same node.
compare.onclick = function() {
alert("Is testElem \=\=\= document.querySelector(\"testElement\"): " + (testElem === document.querySelector("#testElement")));
}
#testElement {
width: 100px;
height: 100px;
background-color: blue;
}
<div id="container">
<div id="testElement"></div>
</div>
<button id="replaceHtml">Replace HTML</button>
<button id="compare">Compare nodes</button>