In chrome, following input element can be dragged and dropped to the bottom area of the input. I expect this behavior.
<input type="file" class="input-file">
<style>
.input-file {
display: block;
width: 300px;
height: 300px;
border: 1px solid red;
margin: 10px;
}
</style>
However, it is different inside Shadow DOM. Following input element can be dragged and dropped to only the "choose file" button located the left top area of the input. Dropped file is opened not chosen when file is droppped to the bottom area of the input.
customElements.define("foo-bar", class extends HTMLElement {
constructor(){
super()
this.attachShadow({mode: "open"}).innerHTML = `
<input type="file" class="input-file">
<style>
.input-file {
display: block;
width: 300px;
height: 300px;
border: 1px solid red;
margin: 10px;
}
</style>
`
}
})
document.body.innerHTML = "<foo-bar></foo-bar>"
I think that this is a bug caused by events not being notified outside of Shadow DOM.
Is there a workaround?
The workaround is to process the drop
event.
this.shadowRoot.querySelector( 'input' ).ondrop = ev => {
console.log( 'dropped in', ev.dataTransfer.items.length )
for ( var i = 0 ; i < ev.dataTransfer.items.length ; i++ ) {
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile()
console.log( 'file[' + i + '].name = ' + file.name )
}
}
ev.preventDefault()
}
Don't forget to invoke the preventDefault()
method to abort the file opening.