jQuery UI 可排序滚动辅助元素偏移 Firefox 问题
Posted
技术标签:
【中文标题】jQuery UI 可排序滚动辅助元素偏移 Firefox 问题【英文标题】:jQuery UI sortable scroll helper element offset Firefox issue 【发布时间】:2011-01-27 22:26:41 【问题描述】:我对 Firefox 3.6 中的 jQuery UI 1.7.2 可排序列表有问题,IE7-8 工作正常。当我向下滚动一点时,辅助元素的偏移量似乎与我的高度相同 从鼠标指针向下滚动,这使得无法看到您最初开始拖动的项目。 如何解决此问题或解决此问题?如果没有修复什么是真正好的替代可拖动插件?
这是我的可排序的初始化参数。
$("#sortable").sortable( placeholder: 'ui-state-highlight' );
$("#sortable").disableSelection();
【问题讨论】:
这是一个演示该错误的 gif(引用自已接受答案中的 jQuery 论坛帖子):i.imgur.com/phYGO.gif 【参考方案1】:如果要防止浏览器嗅探,CSS 唯一的解决方案是将 ul 或容器样式设置为 overflow: auto
。如果你通过 firebug 查看源代码,jQuery 在他们的example 中就是这样做的。
【讨论】:
这是使用 JQuery-UI 可拖动和可放置的唯一对我有用的答案。 这在所有浏览器上都非常适合我,当然是最简单/最干净的解决方案。干杯! 绝对是最干净的解决方案。无法定义容器position:relative
是一个非常严重的限制
这对我有用,而 position:relative
没有,谢谢。
position: static;
和 overflow: auto;
的组合为我做到了【参考方案2】:
使用overflow: auto;
对我来说不是一个选择。我可以使用 sort
事件处理程序解决这个问题:
$(...).sortable(
...
sort: function(event, ui)
var $target = $(event.target);
if (!/html|body/i.test($target.offsetParent()[0].tagName))
var top = event.pageY - $target.offsetParent().offset().top - (ui.helper.outerHeight(true) / 2);
ui.helper.css('top' : top + 'px');
,
...
);
它并不完美,但它不需要浏览器嗅探。在 IE8、Chrome 和 Firefox 中测试。
编辑:这是使用 jQuery 1.10.0 和 jQuery UI 1.10.3。
【讨论】:
天哪,这是一个很棒的解决方案!我喜欢这个,因为它不测试用户代理,也不需要可能破坏其他网站页面布局的更改。 终于有一个有效的修复程序!非常感谢你。你已经在我家中赢得了三代人的青睐。 最后,它也适用于 jQuery UI 1.11.4,谢谢! 这解决了问题,但使containment
选项无用。
您先生是这个解决方案的英雄。谢谢。【参考方案3】:
我看到了这个问题,并且能够通过从我的页面上包含的 div 之一中删除 css 规则 position:relative 来解决它。另见:http://forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff
【讨论】:
为我工作,但由于其他原因,我无法删除职位:相对。相反,@rtcherry 的解决方案适用于我:***.com/a/20225012/72350【参考方案4】:我也遇到了这个问题,用下面的代码解决了:
var wscrolltop = 0;
$sortable_elements.sortable(
start: function(event, ui)
wscrolltop = $(window).scrollTop();
,
sort: function(event, ui)
ui.helper.css('top' : ui.position.top + wscrolltop + 'px');
);
我发现,如果您使用可排序元素滚动,仍然会出现问题。也许有人对此有解决方案?
更新: 解决方法是:
$sortable_elements.sortable(
connectWith: '#personal-favs ul.fitems',
sort: function(event, ui)
ui.helper.css('top' : ui.position.top + $(window).scrollTop() + 'px');
);
但仍然 - 如果您要离开列表,排序事件似乎会停止。
【讨论】:
这对我来说是溢出:自动对我来说不是一个选项。【参考方案5】:您还需要考虑到这是特定于 firefox 的事实,这是我正在使用的 sn-p - 我从 Harris 的解决方案中得到了正确的指导。当可排序对象位于相对定位的容器中时,我在不使用帮助程序的情况下遇到了这个问题。
var options =
handle: '.mover',
update:updateSorting
;
var userAgent = navigator.userAgent.toLowerCase();
if(userAgent.match(/firefox/))
options["start"] = function (event, ui) ui.item.css('margin-top', $(window).scrollTop() ); ;
options["beforeStop"] = function (event, ui) ui.item.css('margin-top', 0 ); ;
$("#" + list_id+"").sortable(options);
$("#" + list_id+"").disableSelection();
您也可以在服务器上进行此检查,然后根据浏览器进行 2 次不同的调用。
【讨论】:
太好了,你在这里为我省了很多麻烦。 这对我来说是一个很好的解决方案,因为我使用的是 jquery 1.4.2 和 jquery-ui.1.8.23,所以我遇到了这个问题,所以现在它会解决。使用 jquery.1.8.js 也可以解决此问题,但是当我将 jquery.1.4.2 替换为 jquery.1.8.js 时遇到了很多问题,所以 thnx 不得不这样做让我感到恶心,但这是唯一有效的解决方案(类似于 50235289)。不过,说真的,我的胃病了。叹息。 实际上通过删除我的 CSS 中的html overflow-x: hidden;
解决了这个问题。不真实。【参考方案6】:
我设法解决了这个问题:
$( "items" ).sortable(
start: function (event, ui)
if( ui.helper !== undefined )
ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() );
,
beforeStop: function (event, ui)
if( ui.offset !== undefined )
ui.helper.css('margin-top', 0);
,
placeholder: 'placeholder-class'
);
基本上,你需要监听 sortable 的 "start" 事件,将浏览器当前的 scrollTop() 值添加到 helper 的位置,然后你需要监听 sortable 的 "beforeStop" 事件,在项目被正式放回列表中的新位置。
希望对某人有所帮助!
【讨论】:
【参考方案7】:我在我的网站上强制使用滚动条,因此由于我的 CSS 中有 html overflow-y: scroll
而出现了这个可滚动偏移问题。
当我打开和关闭可滚动时,我使用以下方法来解决它。我只在 IE8、FF12 和 Chrome 中测试过...
turnSortingOnOff:function(e)
e.preventDefault();
if (stopOrdering())
// get rid of the hacky css on the html element
$('html').css( 'overflow-y': '' );
$('html').css( 'margin-right': '' );
elmt.sortable('disable');
else if (startOrdering())
// if the body is smaller than the window
// then there aren't any scrollbars
// in which case, add a right hand margin of 16px
// to the html to prevent the site wobbling
if ($('body').outerHeight() <= $(window).height())
$('html').css( 'margin-right': 16 );
// then override the overflow-y: scroll
// in the css by setting it to a nice, safe inherit
$('html').css( 'overflow-y': 'inherit' );
elmt.sortable('enable');
显然它不是万无一失的——如果文档大小在排序时发生变化,则必须做其他事情。但是,根据我的经验,在这种情况下它看起来不那么奇怪。
【讨论】:
【参考方案8】:我使用较新的 jQuery/jQuery UI 版本“修复”了这个问题。
jQuery 1.8.0 jQuery UI 1.8.23【讨论】:
我正在使用 jquery 1.8.2 和 jquery ui 1.9,但仍然无法使用【参考方案9】:对于未来的读者 我遇到了一个类似的问题,当在引导对话框的滚动 div 内拖动时,辅助元素有一个偏移量。当释放拖动的对象时,动画将拖动的辅助元素发送到它的新位置,而不考虑页面的滚动部分,这给用户带来了令人困惑的反馈。
为了在对话框容器中使用 position:relative 和 overflow-y:auto,我的解决方案是
1- 在排序开始事件中将scrollTop() 偏移量添加到辅助对象的margin-top;
2- 移除 beforeStop 事件中的 margin-top
这修复了动画在拖动后关闭的问题,但是在页面的滚动部分中拖动时,辅助对象被推到光标下方。最后的修复是
3- 在拖动(使用排序事件)时计算并设置辅助对象的 top 属性,相对于指针和容器偏移量。
$(...).sortable(
...
start: function (event, ui)
ui.helper.css('margin-top', $("#mybootstrap-dialog").scrollTop());
,
beforeStop: function (event, ui)
ui.helper.css('margin-top',0);
,
sort: function(event, ui)
var top = event.clientY - $('#my-sortable-ul').offset().top - $("#mybootstrap-dialog").scrollTop();
ui.helper.css('top' : top + 'px');
,
...
);
帮帮忙
【讨论】:
【参考方案10】:设置overflow: auto
使Firefox 开始拖动指针下的元素,但它也会阻止自动滚动正常工作。您可以在 jQuery Sortable 示例中看到这一点,如果您使窗口足够小以至于需要滚动。
我在 html 标记上有overflow: scroll
,但即使删除它和(我认为)所有相关的包含元素并不能完全解决问题(这意味着拖动正确开始并且自动滚动有效)。我还尝试了 _findRelativeOffset 的 mozilla 嗅探补丁(我认为就是这样),但没有帮助。
对我的用例有帮助的只是拖动克隆(可拖动构造函数中的helper: 'clone'
)。为了让克隆看起来不存在,我添加了 start 和 stop 方法,它们只是将可见性设置为隐藏然后再返回。
我会在上面发表评论,但我还没有要点。
【讨论】:
【参考方案11】:遇到了同样的问题。在我的情况下,不可能使用“溢出:自动”修复。所以这就是我所做的。
var pos_fixed = 1; // switch variable (the fix should only be fired ones)
$('.drag').draggable(
start: function(event, ui)
pos_fixed = 0; // we're about to start, set to not fixed yet
,
drag: function(event, ui)
if(pos_fixed == 0) // check if the fix hasn't been fired for this instance yet
var help_pos = $(ui.helper).offset().top, // get helpers offset
targ_pos = $(event.target).offset().top, // get targets(the dragged elements) offset
marg = targ_pos-help_pos; // calculate the margin the helper has to have to put it on the same y-position as our target
$(ui.helper).css('margin-top', marg); // put our helper on the same y-position as the target
pos_fixed = 1; // we've fixed it, we don't want it to fire again
);
此修复不关心您使用的是什么浏览器。当拖动开始时,它将始终确保助手具有与目标相同的 y 偏移量。
【讨论】:
【参考方案12】:对于有此问题的未来读者。 我从 jqueryui 1.8 升级到 1.10.3 并且没有修复 css 问题就解决了。
http://jqueryui.com/
我也从 jquery 1.8 升级到 1.10.2
http://jquery.com/
【讨论】:
【参考方案13】:总结您的工作并提供完整的解决方案。以下似乎适用于 Chrome 40+ 和 Firefox 30+
var isFirefox = /firefox/.test(navigator.userAgent.toLowerCase());
$('#target').sortable(
connectWith: '#target-holder .elements',
handle: ".element-header",
start: function(ev, ui)
if( isFirefox )
ui.item.css('margin-top', $(window).scrollTop() );
,
sort: function(ev, ui)
if( isFirefox)
ui.helper.css('top' : ui.position.top - $(window).scrollTop() + 'px');
else
ui.helper.css('top' : ui.position.top + $(window).scrollTop() + 'px');
,
beforeStop: function (ev, ui)
if( isFirefox )
ui.item.css('margin-top', 0 );
);
【讨论】:
【参考方案14】:我的解决方案:“.sortable”添加“位置:相对”
$(".sortable").sortable(
sort: function(event, ui)
ui.position.top = ui.position.top + $(window).scrollTop();
,
);
PS 使用 jQuery UI 1.12.0 和 jQuery 2.2.4
【讨论】:
【参考方案15】:sort: function(e, ui)
var tempVariable = $(ui.item.get(0));
tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", "")));
【讨论】:
以上是关于jQuery UI 可排序滚动辅助元素偏移 Firefox 问题的主要内容,如果未能解决你的问题,请参考以下文章
jQuery ui 可拖动元素在滚动 div 之外不能“拖动”
滚动浏览器时使用错误起始位置的可拖动 jQuery UI 元素?