无法通过将文件拖放到按钮外的区域来选择文件,但仅在使用 Shadow 时才在 input 内选择文件 DOM
Cannot choose file by dropping file on area outside the button but inside input only when using Shadow DOM
在chrome中,可以将以下输入元素拖放到输入的底部区域。
我期待这种行为。
<input type="file" class="input-file">
<style>
.input-file {
display: block;
width: 300px;
height: 300px;
border: 1px solid red;
margin: 10px;
}
</style>
但是Shadow内部就不一样了DOM。
可以将以下输入元素拖放到仅位于输入左上方区域的 "choose file" 按钮。
当文件被拖放到输入的底部区域时,拖放的文件未被选择。
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>"
我认为这是由于 Shadow 之外的事件未被通知而导致的错误 DOM。
有解决办法吗?
解决方法是处理 drop
事件。
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()
}
不要忘记调用 preventDefault()
方法来中止文件打开。
在chrome中,可以将以下输入元素拖放到输入的底部区域。 我期待这种行为。
<input type="file" class="input-file">
<style>
.input-file {
display: block;
width: 300px;
height: 300px;
border: 1px solid red;
margin: 10px;
}
</style>
但是Shadow内部就不一样了DOM。 可以将以下输入元素拖放到仅位于输入左上方区域的 "choose file" 按钮。 当文件被拖放到输入的底部区域时,拖放的文件未被选择。
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>"
我认为这是由于 Shadow 之外的事件未被通知而导致的错误 DOM。
有解决办法吗?
解决方法是处理 drop
事件。
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()
}
不要忘记调用 preventDefault()
方法来中止文件打开。