无法使用 Svelte 在 div 上的 drop 事件中阻止 Default()
Can't preventDefault() on drop event on a div with Svelte
我正在尝试在 <div>
上实现一个文件投放器作为 Svelte 组件。我已经尝试了 preventDefault
的所有组合,但浏览器仍然加载拖放的文件而不是将其传递给组件。
<script>
function handleDrop(event) {
event.preventDefault();
console.log("onDrop");
}
function handleDragover(event) {
console.log("dragOver");
}
</script>
<style>
.dropzone {
display: block;
width: 100vw;
height: 300px;
background-color: #555;
}
</style>
<div class="dropzone" on:drop|preventDefault={handleDrop}
on:dragover|once|preventDefault={handleDragover}></div>
我试过在处理函数中使用和不使用 event.preventDefault();
。还尝试使用 on:dragenter
事件和修饰符的不同组合,即使用 stopPropagation
。浏览器仍然打开拖放的文件。我究竟做错了什么?谢谢!
(更新)修复:
好的,罪魁祸首是 |once
修饰符。从 <div>
中的 on:dragover
中删除后,一切正常,除了 dragover
事件在拖过 div 时连续触发。 event.preventDefault();
不需要内部处理程序函数,因为 |preventDefault
修饰符可以正常工作。这是代码(为简洁起见省略 <style>
):
<script>
function handleDrop(event) {
console.log("onDrop");
}
function handleDragover(event) {
console.log("onDragOver");
}
</script>
<div class="dropzone" on:drop|preventDefault={handleDrop}
on:dragover|preventDefault={handleDragover}></div>
还没有提交这个作为答案,因为我想找出为什么我不能对 dragover
事件使用 |once
修饰符,这对我的应用程序很有用。谢谢!
<style>
.dropzone {
display: block;
width: 100vw;
height: 300px;
background-color: #555;
}
</style>
<div class="dropzone" on:drop={event => handleDrop(event)}
on:dragover={handleDragover}>
</div>
<script>
export function handleDragover (ev) {
ev.preventDefault();
console.log("dragOver");
}
export function handleDrop (ev) {
ev.preventDefault();
console.log("onDrop");
}
</script>
看这里:https://svelte.dev/repl/3721cbc9490a4c51b07068944a36a40d?version=3.4.2
https://v2.svelte.dev/repl?version=2.9.10&gist=8a9b145a738530b20d0c3ba138512289
问题:
这是一个根源于 HTML drag-and-drop 的常见陷阱(不是 Svelte 的错),必须取消最后一个 dragover
事件才能取消 drop
。查看 Svelte 的 once 指令,它只是一个运行处理程序一次的闭包。然而,dragover 会在被丢弃之前多次发射,因此不会阻止紧接在前的 dragover。
解法:
只包含没有处理程序的指令:
<div
on:dragover|preventDefault
on:drop|preventDefault={handler}
>
我正在尝试在 <div>
上实现一个文件投放器作为 Svelte 组件。我已经尝试了 preventDefault
的所有组合,但浏览器仍然加载拖放的文件而不是将其传递给组件。
<script>
function handleDrop(event) {
event.preventDefault();
console.log("onDrop");
}
function handleDragover(event) {
console.log("dragOver");
}
</script>
<style>
.dropzone {
display: block;
width: 100vw;
height: 300px;
background-color: #555;
}
</style>
<div class="dropzone" on:drop|preventDefault={handleDrop}
on:dragover|once|preventDefault={handleDragover}></div>
我试过在处理函数中使用和不使用 event.preventDefault();
。还尝试使用 on:dragenter
事件和修饰符的不同组合,即使用 stopPropagation
。浏览器仍然打开拖放的文件。我究竟做错了什么?谢谢!
(更新)修复:
好的,罪魁祸首是 |once
修饰符。从 <div>
中的 on:dragover
中删除后,一切正常,除了 dragover
事件在拖过 div 时连续触发。 event.preventDefault();
不需要内部处理程序函数,因为 |preventDefault
修饰符可以正常工作。这是代码(为简洁起见省略 <style>
):
<script>
function handleDrop(event) {
console.log("onDrop");
}
function handleDragover(event) {
console.log("onDragOver");
}
</script>
<div class="dropzone" on:drop|preventDefault={handleDrop}
on:dragover|preventDefault={handleDragover}></div>
还没有提交这个作为答案,因为我想找出为什么我不能对 dragover
事件使用 |once
修饰符,这对我的应用程序很有用。谢谢!
<style>
.dropzone {
display: block;
width: 100vw;
height: 300px;
background-color: #555;
}
</style>
<div class="dropzone" on:drop={event => handleDrop(event)}
on:dragover={handleDragover}>
</div>
<script>
export function handleDragover (ev) {
ev.preventDefault();
console.log("dragOver");
}
export function handleDrop (ev) {
ev.preventDefault();
console.log("onDrop");
}
</script>
看这里:https://svelte.dev/repl/3721cbc9490a4c51b07068944a36a40d?version=3.4.2
https://v2.svelte.dev/repl?version=2.9.10&gist=8a9b145a738530b20d0c3ba138512289
问题:
这是一个根源于 HTML drag-and-drop 的常见陷阱(不是 Svelte 的错),必须取消最后一个 dragover
事件才能取消 drop
。查看 Svelte 的 once 指令,它只是一个运行处理程序一次的闭包。然而,dragover 会在被丢弃之前多次发射,因此不会阻止紧接在前的 dragover。
解法:
只包含没有处理程序的指令:
<div
on:dragover|preventDefault
on:drop|preventDefault={handler}
>