繁体   English   中英

如何将拖放事件侦听器附加到 React 组件

[英]How to Attach Drag & Drop Event Listeners to a React component

我正在构建一个组件,允许将本地文件拖放到 div 上。 然后是有关已删除文件的信息输出。

我的问题是我不知道如何在创建组件时正确附加事件侦听器dropdragover

我的 App 组件是我所有逻辑所在的地方(用于放置和拖动的处理程序),我创建了一个单独的组件,文件将放置在其中 - dropZone 组件。

我试图把事件侦听器的悬浮窗标签上我的应用程序组件与componentDidMount那里,如果我的悬浮窗组件已经变得把一个事件监听器就可以了:

componentDidMount(){
      const dropZone = document.getElementById('dropZone');
      dropZone.addEventListener('dragover', this.allowDrop.bind(this))
      dropZone.addEventListener('drop', this.dropHandler.bind(this))
    } 

这没有用

然后我尝试将它放在我的应用程序组件上的 dropZone 标签中:

<DropZone dropZone = {"dropZone"} onDragOver = {this.allowDrop.bind(this)} 
 onDrop ={this.dropHandler.bind(this)} >      
</DropZone>

这也没有向 dropZone 添加事件侦听器。 我已经尝试了其他一些事情,但这些是我认为应该工作的事情。

所以我的问题是,

  • 如何将dropdragover事件侦听器添加到 dropZone?

  • 我应该在 App 上添加这些事件侦听器并将它们作为道具传递给 dropZone 组件吗? 或者甚至不需要传递

  • 或者我应该直接在 dropZone 上添加事件侦听器,以便我的事件处理程序函数存在于 dropZone 组件中?

你不需要使用道具。 您可以在 DropZone 组件中添加所有事件。

http://codepen.io/jzmmm/pen/bZjzxN?editors=0011

这是我添加事件的地方:

  componentDidMount() {
    window.addEventListener('mouseup', this._onDragLeave);
    window.addEventListener('dragenter', this._onDragEnter);
    window.addEventListener('dragover', this._onDragOver);
    window.addEventListener('drop', this._onDrop);
    document.getElementById('dragbox').addEventListener('dragleave', this._onDragLeave);
  }

你的渲染方法:

  render() {
    return (
      <div>
        {this.props.children}
        <div id="dragbox" className={this.state.className}>
          Drop a file to Upload
        </div>
      </div>
    );
  }

正如您在 componentDidMount 中看到的,我也向 #dragbox 添加了一个事件侦听器。 因为一旦您将文件拖到页面上,#dragbox 就会位于鼠标光标下方,所以它需要一个 dragleave,以防您决定不想将文件放在那里。

此外,需要dragover来捕获drop

然后在我的 App 组件中,我可以这样使用它:

class App extends React.Component {
  render() {
    return (
      <DropZone>
        <div>
          <h1>Drag A File Here...</h1>
        </div>
      </DropZone>
    );
  }
}

使用样式组件库和 React Hooks 的@mnsr 答案版本

const DragBox = styled.div(({ isVisible }: { isVisible }) =>
    isVisible
        ? `
        position: fixed;
        display: flex;
        border: 15px dashed white;
        width: 100%;
        height: 100%;
        z-index: 2000;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        flex: 1;
        justify-content: center;
        align-items: center;
        text-align: center;
        font-size: 30px;
        font-weight: 600;
        color: white;
        letter-spacing: 1px;
        margin: auto;
`
        : 'display: none;'
);

const DropZone = ({ children }) => {
    const [isVisible, setIsVisible] = useState(false);

    const onDragEnter = useCallback((e) => {
        setIsVisible(true);
        e.stopPropagation();
        e.preventDefault();
        return false;
    }, []);
    const onDragOver = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        return false;
    }, []);
    const onDragLeave = useCallback((e) => {
        setIsVisible(false);
        e.stopPropagation();
        e.preventDefault();
        return false;
    }, []);
    const onDrop = useCallback((e) => {
        e.preventDefault();
        const files = e.dataTransfer.files;
        console.log('Files dropped: ', files);
        // Upload files
        setIsVisible(false);
        return false;
    }, []);

    useEffect(() => {
        window.addEventListener('mouseup', onDragLeave);
        window.addEventListener('dragenter', onDragEnter);
        window.addEventListener('dragover', onDragOver);
        window.addEventListener('drop', onDrop);
        return () => {
            window.removeEventListener('mouseup', onDragLeave);
            window.removeEventListener('dragenter', onDragEnter);
            window.removeEventListener('dragover', onDragOver);
            window.removeEventListener('drop', onDrop);
        };
    }, [onDragEnter, onDragLeave, onDragOver, onDrop]);

    return (
        <div>
            {children}
            <DragBox
                className="bg-secondary"
                isVisible={isVisible}
                onDragLeave={onDragLeave}
            >
                Drop files to Upload
            </DragBox>
        </div>
    );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM