React-dnd: 在子节点上使用translate3d时,DragPreview的位置错误

创建于 2015-08-19  ·  5评论  ·  资料来源: react-dnd/react-dnd

嘿!

我们尝试使元素可拖动,该元素在某些时候包含translate3d css样式。 不幸的是,这重新定位了整个拖动层。 我真的不明白为什么,因为translate3d不在根元素上,而是在它的子节点上。

我整理了一个非常简单的示例,向您展示了问题。 (要使其工作,您需要将ReactDnD.min.js放在“ ./scripts/react-dnd-1.1.4/dist”文件夹中,因为我没有找到任何托管ReactDnD的CDN)。

感谢帮助!

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>DragPreview with wrong position example</title>

        <script src="http://fb.me/react-with-addons-0.13.3.js"></script>
        <script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
        <script src="scripts/react-dnd-1.1.4/dist/ReactDnD.min.js"></script>

        <style>
            .ReactDnDElement {
                background: red;
                overflow: hidden;
                width: 200px;
                height: 100px;
            }

            .ReactDnDElement .wrapper {
                display: flex;
                align-items: center;
                width: 600px;
                height: 100%;
                transform: translate3d(-275px, 0, 0);
            }

            .ReactDnDElement .wrapper div {
                width: 150px;
                height: 50%;
            }

            .ReactDnDElement .wrapper div.green { background: green; }
            .ReactDnDElement .wrapper div.blue { background: blue; }
            .ReactDnDElement .wrapper div.yellow { background: yellow; }
            .ReactDnDElement .wrapper div.magenta { background: magenta; }
        </style>
    </head>

    <body>
        <script type="text/jsx">
            /* ReactDnDApp */

            var ReactDnDApp = React.createClass({
                render: function() {
                    return (
                        <ReactDnDElement></ReactDnDElement>
                    );
                }
            });

            ReactDnDApp = ReactDnD.DragDropContext(ReactDnD.HTML5)(ReactDnDApp)


            /* ReactDnDElement */

            var ReactDnDElement = React.createClass({
                render: function() {
                    return this.props.connectDragSource(
                        this.props.connectDragPreview(
                            <div className="ReactDnDElement">
                                <div className="wrapper">
                                    <div className="green"></div>
                                    <div className="blue"></div>
                                    <div className="yellow"></div>
                                    <div className="magenta"></div>
                                </div>
                            </div>
                        )
                    );
                }
            });

            ReactDnDElement = ReactDnD.DragSource("dndElement", {
                beginDrag: function(props) {
                    return {};
                }
            }, function(connect, monitor) {
                return {
                    connectDragSource: connect.dragSource(),
                    connectDragPreview: connect.dragPreview()
                };
            })(ReactDnDElement);


            /* RUN IT! */

            React.render(React.createElement(ReactDnDApp), document.body);
        </script>
    </body>
</html>
bug wontfix

最有用的评论

好吧,我希望浏览器的家伙尽快解决此问题。

不见得。 HTML5拖放已在IE5行为的基础上进行了标准化,并且已经被打破并且前后不一致。 随着网络变得越来越复杂,我怀疑它只会变得更糟,而不会变得更好。 自定义鼠标和触摸处理是一个更好的解决方案,我期待发布这样的React DnD后端。

所有5条评论

原生html5拖放功能似乎也存在问题。 如果我尝试使用本机html5拖放方法进行相同操作,则它适用于Firefox和Safari,但不适用于Chrome和Opera。

使用react-dnd这个问题在野生动物园中不存在,但对于Chrome,Opera和FIREFOX确实存在。

我已经打开了铬的问题: https :

有修复此错误的意图吗?

讨厌的东西。 我只花了两个小时,却不知道如何使它工作。

这似乎是这些可怕的浏览器不一致之一。 当与您交互的元素的任何子元素的位置相对于其父元素的负偏移量定位时,浏览器对传递给dataTransfer.setDragImage的相同xy值的浏览器的解释会有所不同。 请注意,如何神奇地将变换更改为正变换,才能使其正常工作。

您在Firefox中的一些普通HTML5拖放示例上未看到此问题的原因很可能是因为它们未指定xy ,并且默认值显示为“正常工作” ”。 但是,在大多数情况下,我们需要为出现在正确位置的拖动项指定它们。

我怀疑这里是否有可行的解决方法。 当拖动源节点的任何深层嵌套子级超出其左侧或顶部边缘的范围时, setDragImage(node, x, y)在某些浏览器中将无法正常工作。 同样,即使我们尝试为某些浏览器修复此问题,我们也肯定会在其他浏览器中解决此问题,因此我认为我们无法可靠地修复此问题。

我正在关闭,请随时寻找解决方法! 现在,我建议避免在拖动源内部进行负变换。 请注意,您可以移动connectDragSource _inside_转换后的包装器:

.ReactDnDElement {
    background: red;
    overflow: hidden;
    width: 200px;
    height: 100px;
}

.ReactDnDElement .transform {
    transform: translate3d(-275px, 0, 0);
    width: 100%;
    height: 100%;
}

.ReactDnDElement .wrapper {
    display: flex;
    align-items: center;
    width: 600px;
    height: 100%;
}

.ReactDnDElement .wrapper div {
    width: 150px;
    height: 50%;
}

.ReactDnDElement .wrapper div.green { background: green; }
.ReactDnDElement .wrapper div.blue { background: blue; }
.ReactDnDElement .wrapper div.yellow { background: yellow; }
.ReactDnDElement .wrapper div.magenta { background: magenta; }
var ReactDnDElement = React.createClass({
    render: function() {
      return (
        <div className="ReactDnDElement">
          <div className="transform">
            {this.props.connectDragSource(
              <div className="wrapper">
                <div className="green"></div>
                <div className="blue"></div>
                <div className="yellow"></div>
                <div className="magenta"></div>
              </div>
            )}
          </div>
        </div>
      );
    }
});

但是,通过这种方式,只有子部件将用作拖动图像-不确定是否要这样做。

screen shot 2015-09-17 at 17 48 31

不幸的是,这是我所建议的最好的方法。 如果这对您来说是个大问题,请考虑使用替代的React DnD后端而不是HTML5:例如,像#70那样的鼠标后端,就不会出现此问题,因为它不会依赖setDragImage 。 另一个选择是继续使用HTML5后端,但使用不依赖setDragImage的自定义拖动层

嘿! 感谢您对此的关注。 是的,确实是令人讨厌的东西! 好吧,我希望浏览器的家伙尽快解决此问题。

好吧,我希望浏览器的家伙尽快解决此问题。

不见得。 HTML5拖放已在IE5行为的基础上进行了标准化,并且已经被打破并且前后不一致。 随着网络变得越来越复杂,我怀疑它只会变得更糟,而不会变得更好。 自定义鼠标和触摸处理是一个更好的解决方案,我期待发布这样的React DnD后端。

此页面是否有帮助?
0 / 5 - 0 等级