e.preventDefault()在setTimeout()

时间:2017-11-21 05:14:08

标签: javascript reactjs

场景:移动 - 拖放 - 滚动控件容器

我有一个包含拖放图块数组的div。这些瓷砖水平溢出容器,我希望能够轻松地在容器中滚动,但仍然使用拖放控件。我显然不希望容器在拖动其中一个控件时滚动;我也不希望控件阻止容器滚动。

要阻止页面和容器滚动,您可以在event.preventDefault处理程序中使用touchstart。这很好用,拖动磁贴不会滚动容器。问题是你现在无法在触摸可拖动的瓷砖时滚动容器。

为了解决这个问题,我尝试在组件isDragging中设置一个标志,该标志在touchstart处理程序中的短暂延迟后设置为true,然后在该标志被翻转后阻止默认操作。这不起作用。

示例尝试:

handleDrag( e ) {
    this.dragStartTimeout = setTimeout(() => {
        e.preventDefault();

        this.setState({
            isDragging: true
        });
    }, 50)
}

注意:touchstart事件在componentDidMount中绑定到可拖动元素的ref。这样做是因为您无法在被动事件侦听器中preventDefault。 React使用被动侦听器。

任何人都知道如何解决这个问题?

编辑 - 我明白了。我还需要将touchmove方法中的componentDidMount事件添加到元素ref。完成后,我需要在组件中添加isScrolling标志。在touchmove处理程序中,如果isScrolling为false,我添加了将isDragging设置为true的逻辑。否则,如果滚动则返回false,如果不滚动则返回preventDefault并继续拖动操作。

handleDragStart( e ) {
    this.dragStartTimeout = setTimeout(() => {
        this.setState({
            isDragging: true
        });
    }, 100)
}

handleDragMove( e ) {
    if ( this.isScrolling ) return false

    if ( !this.dragging ) {
        this.isScrolling = true;
        return false;
    }

    e.preventDefault();

    // scroll is now prevent and you can proceed with drag
}

0 个答案:

没有答案