React-dnd: DragPreview est mal positionné lors de l'utilisation de translate3d sur les nœuds enfants

Créé le 19 août 2015  ·  5Commentaires  ·  Source: react-dnd/react-dnd

Hé!

Nous essayons de rendre un élément déplaçable, qui contient un style css translate3d à un moment donné. Malheureusement, cela repositionne toute la couche de glissement. Je ne comprends pas vraiment pourquoi, puisque le translate3d n'est pas sur l'élément racine, mais sur un nœud enfant de celui-ci.

J'ai rassemblé un exemple très simple, vous montrant le problème. (Pour le faire fonctionner, vous devez placer le ReactDnD.min.js dans le dossier "./scripts/react-dnd-1.1.4/dist", car je n'ai trouvé aucun CDN qui héberge ReactDnD).

Merci pour l'aide!

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

Commentaire le plus utile

Eh bien, j'espère que les gars du navigateur résoudront bientôt ce problème.

Pas probable. Le glisser-déposer HTML5 est standardisé au-dessus du comportement d'IE5, et a été interrompu et incohérent pendant des siècles. À mesure que le Web devient plus complexe, je soupçonne que cela ne fera qu'empirer, pas mieux. La gestion personnalisée de la souris et du toucher est une meilleure solution et j'attends avec impatience la publication de ces backends React DnD.

Tous les 5 commentaires

Il semble qu'il y ait également un problème avec la fonctionnalité de glisser-déposer html5 native. Si j'essaye la même chose avec les méthodes natives de glisser-déposer html5, cela fonctionne correctement pour Firefox et Safari, mais pas pour Chrome et Opera.

Avec react-dnd, ce problème n'existe pas dans Safari, mais pour Chrome, Opera ET FIREFOX, c'est le cas.

J'ai ouvert un problème pour le chrome: https://code.google.com/p/chromium/issues/detail?id=525604

Avez-vous l'intention de corriger ce bogue?

Trucs méchants. Je viens de passer deux heures là-dessus et je ne sais pas comment le faire fonctionner.

Cela semble être l'une de ces terribles incohérences du navigateur. Les mêmes valeurs x et y passées à dataTransfer.setDragImage sont interprétées différemment par les navigateurs lorsqu'un enfant de l'élément avec lequel vous avez interagi est positionné avec un décalage négatif par rapport à son parent. Remarquez comment changer la transformation en une transformation positive la fait fonctionner comme par magie.

La raison pour laquelle vous ne voyez pas ce problème sur certains exemples de glisser-déposer HTML5 vanille dans Firefox est probablement parce qu'ils ne spécifient pas x et y , et les valeurs par défaut se révèlent être "juste fonctionner ». Cependant, nous _ avons besoin_ de les spécifier pour l'élément glissé apparaissant au bon endroit dans la plupart des cas.

Je doute qu'il y ait une solution de contournement possible ici. Lorsque l'un des enfants profondément imbriqués du nœud source de glissement est hors de ses limites vers la gauche ou le bord supérieur, setDragImage(node, x, y) cesse de fonctionner correctement dans certains navigateurs. Encore une fois, même si nous essayions de résoudre ce problème pour certains navigateurs, nous le briserions sûrement dans d'autres navigateurs, donc je ne pense pas que nous puissions résoudre ce problème de manière fiable.

Je ferme, mais n'hésitez pas à chercher des solutions de contournement! Pour l'instant, je suggère d'éviter les transformations négatives à l'intérieur des sources de traînée. Notez que vous pouvez déplacer connectDragSource _à l'intérieur_ du wrapper transformé:

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

Cependant, de cette façon, seule la partie enfant sera utilisée comme image de glissement - je ne sais pas si vous le souhaitez.

screen shot 2015-09-17 at 17 48 31

Malheureusement, c'est le meilleur que je puisse suggérer. Si c'est un gros problème pour vous, veuillez envisager d'utiliser un backend React DnD alternatif au lieu de HTML5: par exemple, un backend de souris comme dans # 70, qui n'aurait pas ce problème car il ne dépendrait pas de setDragImage . Une autre option consiste à continuer à utiliser le backend HTML5, mais à utiliser une couche de glissement personnalisée qui ne repose pas sur setDragImage .

Hé! Merci d'avoir regardé ceci. Oui, des trucs méchants! Eh bien, j'espère que les gars du navigateur résoudront bientôt ce problème.

Eh bien, j'espère que les gars du navigateur résoudront bientôt ce problème.

Pas probable. Le glisser-déposer HTML5 est standardisé au-dessus du comportement d'IE5, et a été interrompu et incohérent pendant des siècles. À mesure que le Web devient plus complexe, je soupçonne que cela ne fera qu'empirer, pas mieux. La gestion personnalisée de la souris et du toucher est une meilleure solution et j'attends avec impatience la publication de ces backends React DnD.

Cette page vous a été utile?
0 / 5 - 0 notes