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>
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.
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.
Hilfreichster Kommentar
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.