React的onDrop事件未触发

55

以下是我正在尝试使用的示例代码,其中包括react + TypeScript。 onDragEnter和onDragOver正常工作,但onDrop事件无法正常工作。

import * as React from 'react';

export class FileZone extends React.Component {

  onDragOver = (e) => {
    let event = e as Event;
    event.stopPropagation();
  }

  onDragEnter = (e) => {
    let event = e as Event;
    event.stopPropagation();
  }

  onFileDrop = (e) => {
    let event = e as Event;
    event.stopPropagation();

    console.log("onFileDrop");
    alert("dropped")
  }

  render() {
    return (
      <div
        onDragEnter={this.onDragEnter}
        onDragOver={this.onDragOver}
        onDrop={this.onFileDrop}>
        Drag and drop file here
      </div>)
  }
}
7个回答

130

您必须像这样使用preventDefault()来阻止dragover事件的默认行为:

onDragOver = (e) => {
    let event = e as Event;
    event.stopPropagation();
    event.preventDefault();
}

在编程中,防止 dragover 事件的默认行为 "表示元素是可拖动的位置",可以参考 MDN 文档 这里, 这里这里。然后 drop 事件就会起作用。


4
我遇到了同样的问题,这个方法解决了它。我不确定,但这似乎是React中的一个bug。在使用原生事件时,不需要这样做。 - Ematipico
28
这并不是React中的一个bug,而是拖放事件的工作方式。dragOver 的默认操作是“将当前的拖拽操作重置为无”。因此,除非你取消这一操作,否则拖放操作将无法工作。查看MDN 获取更多信息,他们的示例包括了这个确切的点。 - Alex D
奇怪的行为。这也解决了我的问题。谢谢! - Stan

27

只需在 ondragover 事件上阻止默认行为,它就可以工作。

onDragOver = (event) => {
    event.preventDefault();
}

return (<div onDragOver={this.onDragOver} {...others}>{children}</div>);

5

你的代码存在问题,你需要给 div 分配事件。

render() {
    return (
      <div //you have to remove additional > from here
        onDragEnter={this.onDragEnter}
        onDragOver={this.onDragOver}
        onDrop={this.onFileDrop}>
        Drag and drop file here
      </div>
    )
  }

3
window.ondragover = function(e) { e.preventDefault(); return false };
window.ondrop = function(e) { e.preventDefault(); return false };

这不是在React中应该这样做的方式。 - user4354205

2
浏览器默认情况下会阻止“拖放”操作,因此您需要防止它们这样做!event.preventDefault()可以像您提到的那样处理它。

1
onDrop={files => this.onFileDrop}>

这个应该变成这样:

这个,应该变成这个:

onDrop={this.onFileDrop}>

由于您使用了“this”来调用函数,因此需要将其放在构造函数中:

constructor(props) {
    super(props);

    this.onFileDrop = this.onFileDrop.bind(this);
  }

功能:

onFileDrop(event) { 
 event.preventDefault(); 
 console.log("qwerty")
}

已更新上述代码,但没有运气,顺便说一下,我正在使用TypeScript。 - Prasob
你的 onFileDrop 函数里有什么内容?你有这段代码吗?onFileDrop(event) { event.preventDefault(); console.log("qwerty")} - Savandy

-1
你需要调用函数来启动它(使用括号):
render() {
    return (
      <div>
        onDragEnter={this.onDragEnter}
        onDragOver={() => { return false }}
        onDrop={files => this.onFileDrop()}> // you were missing the "()"
        Drag and drop file here
      </div>)
  }

在React中,如果您在函数名称后打开和关闭括号,则它将被调用多次,而不是您预期的次数。相反,您应该传递一个引用,并且为此,您应该在没有括号的情况下编写它。 - user4354205

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接