Reputation: 10219
I have a basic input[file]
element which I hide. When you click on the #holder
a file explorer pops up. But selecting a file triggers the console.log()
line to be executed twice (on my computer).
You should better run it as a separate file. Cannot provide a "working" demo, but this is the closest I can get to MCVE.
var element = document.getElementById('holder');
element.onclick = function(e) {
var input = document.getElementById('file-input');
input.click();
input.addEventListener("change", function(evt) {
console.log(evt);
Phimij.addFiles(input.files);
}, false);
};
#holder {
border: 10px dashed #ccc;
width: 300px;
height: 300px;
margin: 20px auto;
}
#holder.hover {
border: 10px dashed #333;
}
#file-input {
display: none;
}
<div id="holder">
<input type="file" multiple id="file-input" />
</div>
Upvotes: 3
Views: 4542
Reputation: 1074276
click
events bubble up the ancestry tree. That means a click on your input
will bubble up to your #holder
element and fire your click
handler on it. In your click
handler on #holder
, you fire the click
event on the input
. That's why your browser crashes: You've triggered an infinite loop.
The solution is to hook click
on the input
and tell it not to bubble (propagate); see flagged lines (but keep reading, further notes below):
var element = document.getElementById('holder');
// **** Added vvvv
document.getElementById('file-input').addEventListener("click", function(evt) {
evt.stopPropagation();
}, false);
// *** Added ^^^^
element.onclick = function(e) {
var input = document.getElementById('file-input');
input.click();
input.addEventListener("change", function(evt) {
console.log(evt);
// Phimij.addFiles(input.files);
}, false);
};
#holder {
border: 10px dashed #ccc;
width: 300px;
height: 300px;
margin: 20px auto;
}
#holder.hover {
border: 10px dashed #333;
}
#file-input {
display: none;
}
<div id="holder">
<input type="file" multiple id="file-input" />
</div>
There are a few other things I'd change. You're adding a change
handler to the input every time there's a click
on #holder
; you really only want to do that once. I'd also add that handler before triggering the click.
So for what it's worth, some changes I'd make:
var element = document.getElementById('holder');
var input = document.getElementById('file-input');
element.addEventListener("click", function() {
input.click();
}, false);
input.addEventListener("click", function(evt) {
evt.stopPropagation();
}, false);
input.addEventListener("change", function(evt) {
console.log(evt);
// Phimij.addFiles(input.files);
}, false);
#holder {
border: 10px dashed #ccc;
width: 300px;
height: 300px;
margin: 20px auto;
}
#holder.hover {
border: 10px dashed #333;
}
#file-input {
display: none;
}
<div id="holder">
<input type="file" multiple id="file-input" />
</div>
Upvotes: 4