React-dnd: DragPreview está mal posicionado cuando se usa translate3d en los nodos secundarios

Creado en 19 ago. 2015  ·  5Comentarios  ·  Fuente: react-dnd/react-dnd

¡Oye!

Intentamos hacer que un elemento se pueda arrastrar, que contiene un estilo css de translate3d en algún momento. Desafortunadamente, esto reposiciona toda la capa de arrastre. Realmente no entiendo por qué, ya que translate3d no está en el elemento raíz, sino en un nodo secundario del mismo.

Reuní un ejemplo muy simple, mostrándote el problema. (Para que funcione, debe colocar ReactDnD.min.js en la carpeta "./scripts/react-dnd-1.1.4/dist", ya que no encontré ningún CDN que aloje ReactDnD).

¡Gracias por la ayuda!

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

Comentario más útil

Bueno, espero que los chicos del navegador solucionen este problema pronto.

No es probable. La función de arrastrar y soltar HTML5 está estandarizada sobre el comportamiento de IE5, y se ha roto e inconsistente durante años. A medida que la web se vuelve más compleja, sospecho que solo empeorará, no mejorará. El manejo personalizado del mouse y el tacto es una mejor solución y espero que se publiquen estos backends de React DnD.

Todos 5 comentarios

Parece que también hay un problema con la funcionalidad nativa de arrastrar y soltar html5. Si intento lo mismo con los métodos nativos de arrastrar y soltar html5, funciona correctamente para Firefox y Safari, pero no para Chrome y Opera.

Con react-dnd este problema no existe en safari, pero sí para chrome, opera Y FIREFOX.

Abrí un problema para el cromo: https://code.google.com/p/chromium/issues/detail?id=525604

¿Alguna intención de solucionar este error?

Cosas desagradables. Acabo de pasar dos horas en esto y no tengo idea de cómo hacerlo funcionar.

Esto parece una de esas terribles inconsistencias del navegador. Los mismos valores x y y pasados ​​a dataTransfer.setDragImage son interpretados por los navegadores de manera diferente cuando cualquier elemento secundario del elemento con el que interactuó se posiciona con un desplazamiento negativo respecto a su elemento primario. Observe cómo cambiar la transformación a una positiva mágicamente lo hace funcionar.

La razón por la que no ve este problema en algunos ejemplos vanilla HTML5 de arrastrar y soltar en Firefox es probablemente porque no especifican x y y , y los valores predeterminados resultan ser "simplemente funcionan ”. Sin embargo, _necesitamos_ especificarlos para el elemento arrastrado que aparece en el lugar correcto en la mayoría de los casos.

Dudo que haya alguna solución viable aquí. Cuando alguno de los elementos secundarios profundamente anidados del nodo de origen de arrastre está fuera de sus límites hacia el borde izquierdo o superior, setDragImage(node, x, y) deja de funcionar correctamente en algunos navegadores. Nuevamente, incluso si intentáramos arreglarlo para algunos navegadores, seguramente lo romperíamos en otros navegadores, por lo que no creo que podamos solucionarlo de manera confiable.

Estoy cerrando, ¡pero siéntete libre de buscar soluciones! Por ahora, sugiero evitar las transformaciones negativas dentro de las fuentes de arrastre. Tenga en cuenta que puede mover connectDragSource _ dentro_ del contenedor 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>
      );
    }
});

Sin embargo, de esta manera, solo se utilizará la parte secundaria como imagen de arrastre; no estoy seguro de si lo desea.

screen shot 2015-09-17 at 17 48 31

Desafortunadamente, esto es lo mejor que puedo sugerir. Si este es un gran problema para usted, considere usar un backend React DnD alternativo en lugar de HTML5: por ejemplo, un backend de mouse como en el # 70, que no tendría este problema porque no dependería de setDragImage . Otra opción es seguir usando el backend HTML5, pero usar una capa de arrastre personalizada que no dependa de setDragImage .

¡Oye! Gracias por echarle un vistazo a esto. ¡Sí, cosas desagradables! Bueno, espero que los chicos del navegador solucionen este problema pronto.

Bueno, espero que los chicos del navegador solucionen este problema pronto.

No es probable. La función de arrastrar y soltar HTML5 está estandarizada sobre el comportamiento de IE5, y se ha roto e inconsistente durante años. A medida que la web se vuelve más compleja, sospecho que solo empeorará, no mejorará. El manejo personalizado del mouse y el tacto es una mejor solución y espero que se publiquen estos backends de React DnD.

¿Fue útil esta página
0 / 5 - 0 calificaciones