React-dnd: DragPreview ist falsch positioniert, wenn translate3d auf untergeordneten Knoten verwendet wird

Erstellt am 19. Aug. 2015  ·  5Kommentare  ·  Quelle: react-dnd/react-dnd

Hallo!

Wir versuchen, ein Element ziehbar zu machen, das irgendwann einen translate3d-CSS-Stil enthält. Leider positioniert dies die gesamte Drag-Ebene neu. Ich verstehe nicht wirklich warum, da sich translate3d nicht auf dem Stammelement befindet, sondern auf einem untergeordneten Knoten davon.

Ich habe ein sehr einfaches Beispiel zusammengestellt, das Ihnen das Problem zeigt. (Damit es funktioniert, müssen Sie ReactDnD.min.js im Ordner "./scripts/react-dnd-1.1.4/dist" ablegen, da ich kein CDN gefunden habe, das ReactDnD hostet.)

Danke für die Hilfe!

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

Hilfreichster Kommentar

Nun, ich hoffe, die Browser-Leute beheben dieses Problem bald.

Unwahrscheinlich. HTML5 Drag & Drop ist zusätzlich zum IE5-Verhalten standardisiert und seit Ewigkeiten fehlerhaft und inkonsistent. Wenn das Web komplexer wird, wird es vermutlich nur schlechter, nicht besser. Benutzerdefiniertes Maus- und Touch-Handling ist eine bessere Lösung und ich freue mich darauf, solche React DnD-Backends zu veröffentlichen.

Alle 5 Kommentare

Anscheinend gibt es auch ein Problem mit der nativen HTML5-Drag & Drop-Funktion. Wenn ich das gleiche mit den nativen HTML5-Drag & Drop-Methoden versuche, funktioniert es korrekt für Firefox und Safari, aber nicht für Chrome und Opera.

Mit react-dnd gibt es dieses Problem nicht in Safari, aber für Chrome, Oper UND FIREFOX.

Ich habe ein Problem für Chrom geöffnet: https://code.google.com/p/chromium/issues/detail?id=525604

Irgendwelche Absichten, diesen Fehler zu beheben?

Böses Zeug. Ich habe gerade zwei Stunden damit verbracht und ich habe keine Ahnung, wie ich es zum Laufen bringen soll.

Dies scheint eine dieser schrecklichen Browser-Inkonsistenzen zu sein. Die gleichen x und y -Werte, die an dataTransfer.setDragImage werden, werden von Browsern unterschiedlich interpretiert, wenn ein untergeordnetes Element des Elements, mit dem Sie interagiert haben, mit einem negativen Versatz zu seinem übergeordneten Element positioniert ist. Beachten Sie, wie das Ändern der Transformation in eine positive auf magische Weise funktioniert.

Der Grund, warum Sie dieses Problem bei einigen Vanille-HTML5-Drag & Drop-Beispielen in Firefox nicht sehen, liegt wahrscheinlich darin, dass sie nicht x und y angeben und die Standardwerte sich als "einfach funktionieren" herausstellen ”. Wir müssen sie jedoch für das gezogene Element angeben, das in den meisten Fällen an der richtigen Stelle angezeigt wird.

Ich bezweifle, dass es hier eine mögliche Problemumgehung gibt. Wenn sich eines der tief verschachtelten untergeordneten Elemente des Drag-Source-Knotens außerhalb der Grenzen links oder oben befindet, funktioniert setDragImage(node, x, y) in einigen Browsern nicht mehr ordnungsgemäß. Selbst wenn wir versuchen würden, das Problem für einige Browser zu beheben, würden wir dies sicherlich in anderen Browsern beheben, sodass ich nicht glaube, dass wir dies zuverlässig beheben können.

Ich schließe, aber Sie können nach Problemumgehungen suchen! Im Moment würde ich vorschlagen, negative Transformationen in Drag-Quellen zu vermeiden. Beachten Sie, dass Sie connectDragSource _in den transformierten Wrapper verschieben können:

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

Auf diese Weise wird jedoch nur der untergeordnete Teil als Ziehbild verwendet - nicht sicher, ob Sie dies möchten.

screen shot 2015-09-17 at 17 48 31

Leider ist dies das Beste, was ich vorschlagen kann. Wenn dies ein großes Problem für Sie ist, sollten Sie ein alternatives React DnD-Backend anstelle von HTML5 verwenden: Zum Beispiel ein Maus-Backend wie in # 70, das dieses Problem nicht hätte, da es nicht auf setDragImage angewiesen wäre eine benutzerdefinierte Drag-Ebene zu verwenden, die nicht auf setDragImage basiert.

Hallo! Vielen Dank für Ihren Blick. Ja, böses Zeug! Nun, ich hoffe, die Browser-Leute beheben dieses Problem bald.

Nun, ich hoffe, die Browser-Leute beheben dieses Problem bald.

Unwahrscheinlich. HTML5 Drag & Drop ist zusätzlich zum IE5-Verhalten standardisiert und seit Ewigkeiten fehlerhaft und inkonsistent. Wenn das Web komplexer wird, wird es vermutlich nur schlechter, nicht besser. Benutzerdefiniertes Maus- und Touch-Handling ist eine bessere Lösung und ich freue mich darauf, solche React DnD-Backends zu veröffentlichen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen