jQuery UI 可排序滚动辅助元素抵消 Firefox 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2451528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery UI sortable scroll helper element offset Firefox issue
提问by James
I have a problem with a jQuery UI 1.7.2 sortable list in Firefox 3.6, IE7-8 work fine. When I'm scrolled down a bit, the helper element seems to have an offset of the same height that I'm scrolled down from the mouse pointer which makes it impossible to see which item you originally started dragging. How do I fix this or work around the issue? If there is no fix what is a really good alternative drag-able plugin?
我在 Firefox 3.6 中的 jQuery UI 1.7.2 可排序列表有问题,IE7-8 工作正常。当我向下滚动一点时,辅助元素的偏移量似乎与我从鼠标指针向下滚动时的高度相同,这使得无法看到您最初开始拖动的项目。如何解决此问题或解决此问题?如果没有修复,什么是真正好的替代可拖动插件?
Here are my initialization parameters for the sortable.
这是我的 sortable 初始化参数。
$("#sortable").sortable( {placeholder: 'ui-state-highlight' } );
$("#sortable").disableSelection();
采纳答案by craig
I was seeing this issue and was able to solve it by removing the css rule position:relative from one of the containing divs on my page. See also: http://forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff
我看到了这个问题,并且能够通过从我的页面上的一个包含 div 中删除 css 规则 position:relative 来解决它。另见:http: //forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff
回答by munch
If you want to prevent browser sniffing, the CSS only solution is to set the ul or a container style to overflow: auto
. If you look at the source through firebug, it's the way jQuery does it in their example.
如果要防止浏览器嗅探,CSS 唯一的解决方案是将 ul 或容器样式设置为overflow: auto
. 如果您通过 firebug 查看源代码,那么 jQuery 在他们的示例中就是这样做的。
回答by rtcherry
Using overflow: auto;
was not an option for me. I was able to work around this issue with this sort
event handler:
使用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'});
}
},
...
});
It is not perfect, but it doesn't require browser sniffing. Tested in IE8, Chrome and Firefox.
它并不完美,但它不需要浏览器嗅探。在 IE8、Chrome 和 Firefox 中测试。
Edit: This is using jQuery 1.10.0 and jQuery UI 1.10.3.
编辑:这是使用 jQuery 1.10.0 和 jQuery UI 1.10.3。
回答by Theodor
I also had this problem and fixed it with the following code:
我也遇到了这个问题并使用以下代码修复了它:
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'});
}
});
I discovered, that there still is a problem if you scroll with your sortable-element. Maybe somebody has a solution for this?
我发现,如果您使用可排序元素滚动,仍然存在问题。也许有人对此有解决方案?
UPDATE: The fix is:
更新:修复是:
$sortable_elements.sortable({
connectWith: '#personal-favs ul.fitems',
sort: function(event, ui) {
ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
}
});
But still - if you're leaving the list, the sort-event seems to stop.
但是 - 如果你离开列表,排序事件似乎停止了。
回答by Russell
You also need to account for the fact this is specific to firefox, here is the snippet I'm using - I got directed the right way from Harris' solution. I encountered this problem w/o using the helper when the sortable was in a relatively positioned container.
您还需要考虑到这是特定于 Firefox 的事实,这是我正在使用的代码段 - 我从 Harris 的解决方案中得到了正确的指导。当 sortable 位于相对定位的容器中时,我在不使用帮助程序的情况下遇到了这个问题。
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();
You could also do this check on the server and then have 2 different calls depending on the browser.
您也可以在服务器上进行此检查,然后根据浏览器进行 2 次不同的调用。
回答by Jonathan Harris
I managed to figure out a fix for this:
我设法解决了这个问题:
$( "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'
});
Basically, you need to listen for the sortable's "start" event to add the browser's current scrollTop() value to the helper's position, and then you need to listen for the sortable's "beforeStop" event, to remove that offset before the item is officially placed back into the list at its new position.
基本上,您需要监听 sortable 的“start”事件以将浏览器的当前 scrollTop() 值添加到 helper 的位置,然后您需要监听 sortable 的“beforeStop”事件,以在项目正式发布之前删除该偏移量放回列表中的新位置。
Hope that's helpful to someone!
希望这对某人有帮助!
回答by DaveJenni
I force scrollbars on my site so this scrollable offset problem occurs due to having html { overflow-y: scroll }
in my CSS.
我在我的网站上强制使用滚动条,因此由于html { overflow-y: scroll }
在我的 CSS 中出现了这个可滚动偏移问题。
As I turn scrollable on and off, I used the following to get around it. I've only tested it in IE8, FF12 and Chrome...
当我打开和关闭可滚动时,我使用以下方法来解决它。我只在 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');
}
}
Obviously it's not bulletproof - if the document size changes while sorting then other things will have to be done. However, in my experience it looks less weird under those circumstances.
显然它不是防弹的 - 如果在排序时文档大小发生变化,则必须完成其他事情。但是,根据我的经验,在这种情况下它看起来不那么奇怪。
回答by Jorge Morante
I "fixed" this using newer jQuery/jQuery UI versions.
我使用较新的 jQuery/jQuery UI 版本“修复”了这个问题。
- jQuery 1.8.0
- jQuery UI 1.8.23
- jQuery 1.8.0
- jQuery UI 1.8.23
回答by Jean-Sébastien Gervais
For future readers I ran into a similar problem where the helper element has an offset when dragging inside the scrolled div of a bootstrap dialog. When releasing the dragged object, the animation sends the dragged helper element towards it's new position without considering the scrolled portion of the page, which gives a confusing feedback to users.
对于未来的读者,我遇到了类似的问题,即在引导程序对话框的滚动 div 内拖动时,辅助元素具有偏移量。当释放被拖动的对象时,动画将被拖动的辅助元素发送到它的新位置,而不考虑页面的滚动部分,这会给用户带来混乱的反馈。
In order to keep things working with position:relative and overflow-y:auto in the dialog container, my solution was
为了让对话容器中的 position:relative 和 overflow-y:auto 保持正常工作,我的解决方案是
1- Add the scrollTop() offset to the margin-top on the helper object in the sort start event;
1- 在排序开始事件中将 scrollTop() 偏移量添加到辅助对象上的边距顶部;
2- remove the margin-top in the beforeStop event
2- 删除 beforeStop 事件中的边距顶部
This fixed the animation from being off after draging, but the helper object is pushed below the cursor while dragging in the scrolled portion in the page. The last fix is
这修复了拖动后动画关闭的问题,但是在页面中的滚动部分拖动时,助手对象被推到光标下方。最后的修复是
3- Calculate and set the top property of the helper object while dragging (using the sort event) relative to the pointer and the container offset.
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'});
}
},
...
});
});
Help this helps
帮助这有帮助
回答by Lorenz Lo Sauer
To summarize your efforts and provide a completed solution. The following seemed to work for Chrome 40+ and Firefox 30+
总结您的努力并提供完整的解决方案。以下似乎适用于 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 );
}
}
});