React-dnd: DragPreview está posicionado incorretamente ao usar translate3d em nós filhos

Criado em 19 ago. 2015  ·  5Comentários  ·  Fonte: react-dnd/react-dnd

Ei!

Tentamos fazer um elemento arrastável, que contém um estilo css translate3d em algum ponto. Infelizmente, isso reposiciona toda a camada de arrasto. Eu realmente não entendo o porquê, já que o translate3d não está no elemento raiz, mas em um nó filho dele.

Montei um exemplo bem simples, mostrando o problema para você. (Para fazer funcionar, você precisa colocar o ReactDnD.min.js na pasta "./scripts/react-dnd-1.1.4/dist", pois não encontrei nenhum CDN que hospede o ReactDnD).

Obrigado pela ajuda!

<!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

Comentários muito úteis

Bem, espero que os caras do navegador corrijam esse problema em breve.

Não é provável. Arrastar e soltar do HTML5 é padronizado em cima do comportamento IE5 e está quebrado e inconsistente há muito tempo. À medida que a web fica mais complexa, suspeito que só vai piorar, não melhorar. O manuseio personalizado do mouse e do toque é uma solução melhor e estou ansioso para que os back-ends do React DnD sejam publicados.

Todos 5 comentários

Parece que há um problema com a funcionalidade de arrastar e soltar html5 nativa também. Se eu tentar o mesmo com os métodos nativos de arrastar e soltar html5, ele funciona corretamente para o Firefox e o safari, mas não para o Chrome e o Opera.

Com o react-dnd, este problema não existe no safari, mas sim no chrome, opera e FIREFOX.

Abri um problema para o chromium: https://code.google.com/p/chromium/issues/detail?id=525604

Alguma intenção de corrigir esse bug?

Coisas desagradáveis. Acabei de passar duas horas nisso e não tenho ideia de como fazer funcionar.

Isso parece uma daquelas terríveis inconsistências do navegador. Os mesmos x e y valores passados ​​para dataTransfer.setDragImage são interpretados pelos navegadores de forma diferente quando qualquer filho do elemento com o qual você interagiu é posicionado com um deslocamento negativo para seu pai. Observe como mudar a transformação para positiva magicamente faz com que funcione.

O motivo pelo qual você não vê esse problema em alguns exemplos simples de arrastar e soltar HTML5 no Firefox é provavelmente porque eles não especificam x e y , e os valores padrão acabam sendo “apenas funcionam ”. No entanto, _precisamos_ especificá-los para o item arrastado que aparece no local certo na maioria dos casos.

Duvido que haja alguma solução alternativa viável aqui. Quando qualquer um dos filhos profundamente aninhados do nó de origem de arrastar estão fora de seus limites para a borda esquerda ou superior, setDragImage(node, x, y) para de funcionar corretamente em alguns navegadores. Novamente, mesmo se tentássemos consertar para alguns navegadores, com certeza quebraríamos isso em outros navegadores, então não acho que podemos consertar isso de forma confiável.

Estou fechando, mas fique à vontade para procurar soluções alternativas! Por enquanto, sugiro evitar transformações negativas dentro de fontes de arrasto. Observe que você pode mover connectDragSource _inside_ o invólucro transformado:

.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>
      );
    }
});

No entanto, desta forma, apenas a parte filha será usada como a imagem de arrastar - não tenho certeza se você deseja isso.

screen shot 2015-09-17 at 17 48 31

Infelizmente, isso é o melhor que posso sugerir. Se este for um grande problema para você, considere usar um backend React DnD alternativo em vez de HTML5: por exemplo, um backend de mouse como em # 70, que não teria esse problema porque não dependeria de setDragImage . Outra opção é continuar usando o back-end HTML5, mas use uma camada de arrastar personalizada que não depende de setDragImage .

Ei! Obrigado por dar uma olhada nisso. Sim coisas desagradáveis, de fato! Bem, espero que os caras do navegador corrijam esse problema em breve.

Bem, espero que os caras do navegador corrijam esse problema em breve.

Não é provável. Arrastar e soltar do HTML5 é padronizado em cima do comportamento IE5 e está quebrado e inconsistente há muito tempo. À medida que a web fica mais complexa, suspeito que só vai piorar, não melhorar. O manuseio personalizado do mouse e do toque é uma solução melhor e estou ansioso para que os back-ends do React DnD sejam publicados.

Esta página foi útil?
0 / 5 - 0 avaliações