Javascript 可拖动和边距:0自动;
jQuery UI sortable/Dragable存在一个问题,如果要拖动的元素使用Javascript 可拖动和边距:0自动;,javascript,jquery,css,jquery-ui,Javascript,Jquery,Css,Jquery Ui,jQuery UI sortable/Dragable存在一个问题,如果要拖动的元素使用margin:0 auto居中,则拖动从容器的左侧开始,而不是从元素实际所在的中心开始 这里有一个演示来说明我的意思:。只需拖动红方块 如果从“.drag”元素中删除margin:0 auto,您将看到拖动正常开始 使用margin:0 auto居中时,如何解决此问题并让元素从实际位置拖动 这似乎发生在谷歌浏览器上 $(“#c”).sortable() 用CSS“calc”将元素居中可以解决这个问题,但我的元
margin:0 auto
居中,则拖动从容器的左侧开始,而不是从元素实际所在的中心开始
这里有一个演示来说明我的意思:。只需拖动红方块
如果从“.drag”元素中删除margin:0 auto
,您将看到拖动正常开始
使用margin:0 auto
居中时,如何解决此问题并让元素从实际位置拖动
这似乎发生在谷歌浏览器上
$(“#c”).sortable()代码>
用CSS“calc”将元素居中可以解决这个问题,但我的元素宽度可以动态更改。此外,“calc”的支持不如“margin”
将draggable包装到容器中解决了这个问题,但HTML更改并不是我想要的解决方案
更新:
所以这不是jQuery的bug。这是谷歌浏览器的一个缺陷。显然,chrome检索到了错误的位置,因此jQuery从chrome告诉它元素所在的位置开始拖动。我在控制台中输出元素的左侧位置,您可以看到它是13px,但显然不是。我想知道是否有人报告过这个错误
解决方案
多亏了朱利安·格雷戈尔
注意:此解决方案可能需要一种刷新助手位置的方法。嘿,我正在测试您的代码笔,并在两个不同的浏览器(Mozilla和Chrome)中进行了检查
我知道你说的是关于Chrome的。但在Mozilla中,它工作得很好
而在chrome位置左侧的属性值不同。在Mozilla中是指拖动时向左:560px,在Chrome中是从左开始:0
这就是为什么要从左侧戏剧性地显示拖动元素的原因
我希望它能帮助你 更新jQuery以添加克隆帮助程序:
$("#c").sortable({
helper: "clone"
});
并更新CSS以添加位置和溢出:
#c {
width: 100%;
padding: 50px 0px;
border: solid 5px;
box-sizing: border-box;
overflow: hidden;
position: relative;
}
我找到的解决办法是
如果无法使用CSS设置中心,则使用calc
而不是CSS中的自动另一个选项是使用JQuery设置中心。
请查看我根据您的反馈和要求在您的代码中更新的演示,您在本文和其他人的回答中解释了这些反馈和要求
在Chrome上,当您使用margin:0 auto
并将left
位置设置为0
时,似乎无法正确计算元素的位置。所以我想你们应该找到另一种方法来水平居中你们的元素
一个选项是在父元素上使用text align:center
,在子元素上使用display:inline block
$(“#c”).sortable()代码>
#c{
宽度:100%;
填充:50px 0px;
边框:实心5px;
框大小:边框框;
文本对齐:居中;
}
.拖{
宽度:200px;
高度:200px;
背景色:红色;
显示:内联块;
}
Chrome返回的位置与Firefox不同,但是您可以使用偏移量来获得正确的坐标,这是sortable使用的。问题在于,在鼠标启动时,边距会从计算中删除,这在设置边距时可能有意义。但使用自动保证金会造成这个问题
您可以添加一个选项来忽略页边距并修改\u mouseStart。像这样:
$("#c").sortable({
ignoreMargins: true
});
$.ui.sortable.prototype._mouseStart = function(event, overrideHandle, noActivation) {
...
if (!this.options.ignoreMargins) {
this.offset = {
top: this.offset.top - this.margins.top,
left: this.offset.left - this.margins.left
};
}
...
}
编辑:
如果不想修改插件,可以使用开始和停止事件。一个问题是,很难检查边距是否已设置为自动,因此您在可排序调用中定义它们,这并不像应该的那样灵活,或者您找到了一种方法来检查哪些边距是自动动态的
$("#c").sortable({
start: function(e, ui) {
var marginsToSet = ui.item.data().sortableItem.margins;
// You set the margins here, so they don't go back to 0
// once the item is put in absolute position
ui.item.css('margin-left', marginsToSet.left);
ui.item.css('margin-top', marginsToSet.top);
},
stop: function(e, ui) {
// Then you need to set the margins back once you stop dragging.
// Ideally this should be dynamic, but you have to be able
// to check which margins are set to auto, which as you'll
// see if you look for some answers on this site,
// doesn't look that simple.
ui.item.css('margin', '20px auto');
}
});
我正在使用FirefoxDeveloperEdition,但我看不到它在firefox上工作的错误。这意味着这是一个Chrome问题,在Chrome上尝试一下,你会看到。感谢这个解决方案,但这不是我想要的,因为我必须将我的许多元素包装在一个容器中,而这个容器就是被拖动的。不是红场本身。虽然这可能是一个很好的解决方案,其他人绊倒在这篇文章在未来Calc似乎不会自动中心元素的宽度。而且它没有良好的浏览器兼容性。我必须继续查找我已经在chrome和firefox上测试过了,它运行良好,如果以正确的方式编写,calc将成为元素中心,即calc(元素的100%宽度/2)
它支持我的情况下几乎所有的主要浏览器元素都会不断动态变化。所以calc不是我的选择。文本对齐方法可能是我要研究的东西,但我会等待更好的选择。问题不在于jquery。这可能是我正在寻找的解决方案,它现在似乎正在发挥作用。看起来它正在改变很多jQuery的核心内容。这安全吗?这会带来什么问题?我遇到了一个问题。如果元素具有边距顶部,则水平固定的相同内容现在垂直发生。在绝对位置时,一旦您的边距值不是0px,就会出现问题。这就是为什么我建议能够切换一个选项,因为它不会在所有情况下都起作用。也就是说,可能还有其他副作用,但通常通过最少的测试,您应该能够看到它在实际情况下是否有效。至于安全性,您只添加一个没有关联的选项,并跳过一条语句。但这并不理想。通过此更改,您始终可以从原始排序表创建另一个排序表。或者尝试使用start event复制此行为。关于页边距顶部问题,请参阅前面的注释,这是因为在绝对位置时,页边距为非0。也许还有其他方法可以解决这个问题,但是如果你想保留自动保证金的话
$("#c").sortable({
ignoreMargins: true
});
$.ui.sortable.prototype._mouseStart = function(event, overrideHandle, noActivation) {
...
if (!this.options.ignoreMargins) {
this.offset = {
top: this.offset.top - this.margins.top,
left: this.offset.left - this.margins.left
};
}
...
}
$("#c").sortable({
start: function(e, ui) {
var marginsToSet = ui.item.data().sortableItem.margins;
// You set the margins here, so they don't go back to 0
// once the item is put in absolute position
ui.item.css('margin-left', marginsToSet.left);
ui.item.css('margin-top', marginsToSet.top);
},
stop: function(e, ui) {
// Then you need to set the margins back once you stop dragging.
// Ideally this should be dynamic, but you have to be able
// to check which margins are set to auto, which as you'll
// see if you look for some answers on this site,
// doesn't look that simple.
ui.item.css('margin', '20px auto');
}
});