Привет!
Мы пытаемся сделать элемент перетаскиваемым, который в какой-то момент содержит стиль translate3d css. К сожалению, это перемещает весь слой перетаскивания. Я не совсем понимаю, почему, поскольку translate3d находится не в корневом элементе, а в его дочернем узле.
Я собрал очень простой пример, показывающий вам проблему. (Чтобы заставить его работать, вам нужно поместить ReactDnD.min.js в папку "./scripts/react-dnd-1.1.4/dist", поскольку я не нашел ни одного CDN, на котором размещен ReactDnD).
Спасибо за помощь!
<!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>
Похоже, есть проблема с встроенной функцией перетаскивания HTML5. Если я попробую то же самое с собственными методами перетаскивания html5, он будет работать правильно для Firefox и Safari, но не для Chrome и Opera.
С react-dnd этой проблемы нет в Safari, но для Chrome, Opera И FIREFOX она есть.
Я открыл проблему для хрома: https://code.google.com/p/chromium/issues/detail?id=525604
Есть ли намерения исправить эту ошибку?
Гадость. Я потратил на это два часа и понятия не имею, как заставить его работать.
Это похоже на одну из тех ужасных несоответствий в браузере. Те же значения x
и y
переданные в dataTransfer.setDragImage
, интерпретируются браузерами по-разному, когда любой дочерний элемент элемента, с которым вы взаимодействуете, позиционируется с отрицательным смещением по отношению к его родительскому элементу. Обратите внимание, как изменение преобразования на положительное волшебным образом заставляет его работать.
Причина, по которой вы не видите этой проблемы в некоторых примерах перетаскивания ванильного HTML5 в Firefox, вероятно, потому, что они не указывают x
и y
, а значения по умолчанию оказываются «просто работают. ». Однако нам _необходимо_ указать их, чтобы перетаскиваемый элемент в большинстве случаев появлялся в нужном месте.
Я сомневаюсь, что здесь есть какое-либо возможное обходное решение. Когда любой из глубоко вложенных дочерних узлов узла источника перетаскивания выходит за его пределы слева или от верхнего края, setDragImage(node, x, y)
перестает правильно работать в некоторых браузерах. Опять же, даже если бы мы попытались исправить это для некоторых браузеров, мы наверняка сломали бы это в других браузерах, поэтому я не думаю, что мы можем надежно исправить это.
Я закрываюсь, но не стесняйтесь искать обходные пути! На данный момент я бы посоветовал избегать отрицательных преобразований внутри источников перетаскивания. Обратите внимание, что вы можете переместить connectDragSource
_внутри преобразованной оболочки:
.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>
);
}
});
Однако таким образом только дочерняя часть будет использоваться в качестве перетаскиваемого изображения - не уверен, что вы этого хотите.
К сожалению, это лучшее, что я могу предложить. Если для вас это большая проблема, рассмотрите возможность использования альтернативного бэкэнда React DnD вместо HTML5: например, бэкэнда мыши, как в # 70, у которого не будет этой проблемы, потому что он не будет полагаться на setDragImage
. Другой вариант - продолжать использовать бэкэнд HTML5, но использовать настраиваемый слой перетаскивания, который не зависит от setDragImage
.
Привет! Спасибо, что посмотрели на это. Да, действительно гадость! Что ж, я надеюсь, что браузеры исправят эту проблему в ближайшее время ..
Что ж, я надеюсь, что браузеры исправят эту проблему в ближайшее время ..
Скорее всего, не. Перетаскивание HTML5 стандартизовано поверх поведения IE5, и долгое время было некорректным и непоследовательным. Я подозреваю, что по мере того, как сеть становится все более сложной, она будет только хуже, а не лучше. Настраиваемая мышь и обработка касаний - лучшее решение, и я с нетерпением жду публикации таких бэкэндов React DnD.
Самый полезный комментарий
Скорее всего, не. Перетаскивание HTML5 стандартизовано поверх поведения IE5, и долгое время было некорректным и непоследовательным. Я подозреваю, что по мере того, как сеть становится все более сложной, она будет только хуже, а не лучше. Настраиваемая мышь и обработка касаний - лучшее решение, и я с нетерпением жду публикации таких бэкэндов React DnD.