React-dnd: DragPreview позиционируется неправильно при использовании translate3d на дочерних узлах

Созданный на 19 авг. 2015  ·  5Комментарии  ·  Источник: react-dnd/react-dnd

Привет!

Мы пытаемся сделать элемент перетаскиваемым, который в какой-то момент содержит стиль translate3d css. К сожалению, это перемещает весь слой перетаскивания. Я не совсем понимаю, почему, поскольку translate3d находится не в корневом элементе, а в его дочернем узле.

Я собрал очень простой пример, показывающий вам проблему. (Чтобы заставить его работать, вам нужно поместить ReactDnD.min.js в папку "./scripts/react-dnd-1.1.4/dist", поскольку я не нашел ни одного CDN, на котором размещен ReactDnD).

Спасибо за помощь!

<!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 этой проблемы нет в Safari, но для Chrome, Opera И FIREFOX она есть.

Я открыл проблему для хрома: https://code.google.com/p/chromium/issues/detail?id=525604

Есть ли намерения исправить эту ошибку?

Гадость. Я потратил на это два часа и понятия не имею, как заставить его работать.

Это похоже на одну из тех ужасных несоответствий в браузере. Те же значения x и y переданные в dataTransfer.setDragImage , интерпретируются браузерами по-разному, когда любой дочерний элемент элемента, с которым вы взаимодействуете, позиционируется с отрицательным смещением по отношению к его родительскому элементу. Обратите внимание, как изменение преобразования на положительное волшебным образом заставляет его работать.

Причина, по которой вы не видите этой проблемы в некоторых примерах перетаскивания ванильного HTML5 в Firefox, вероятно, потому, что они не указывают x и y , а значения по умолчанию оказываются «просто работают. ». Однако нам _необходимо_ указать их, чтобы перетаскиваемый элемент в большинстве случаев появлялся в нужном месте.

Я сомневаюсь, что здесь есть какое-либо возможное обходное решение. Когда любой из глубоко вложенных дочерних узлов узла источника перетаскивания выходит за его пределы слева или от верхнего края, setDragImage(node, x, y) перестает правильно работать в некоторых браузерах. Опять же, даже если бы мы попытались исправить это для некоторых браузеров, мы наверняка сломали бы это в других браузерах, поэтому я не думаю, что мы можем надежно исправить это.

Я закрываюсь, но не стесняйтесь искать обходные пути! На данный момент я бы посоветовал избегать отрицательных преобразований внутри источников перетаскивания. Обратите внимание, что вы можете переместить connectDragSource _внутри преобразованной оболочки:

.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 рейтинги