IE7/8 jquery sortable is causing window to snap to top
I have an IE related issue where, whenever the window is sized to have a viewport smaller than the available content (e.g. window mode), a scroll bar becomes available [normal behavior]. In IE 7 / 8 only (9 only has this issue in compatibility mode and doesn't work without compatibility mode (and I know about the IE9 jquery.sortable issue)), when I need to scroll down on the page to interact with these elements, the window snaps back to the top of the page the moment I start dragging one of the elements, causing the fieldsets to move outside of the viewport. This is not a problem in othe开发者_如何学JAVAr browsers, or when the window content has not been scrolled.
At the bottom of my content, I have a jquery sortable div with two fieldsets inside of it. The normal behavior for interacting with the data in these fieldsets (contained within a common div) is dragging unordered list-items (ul > li) between the two.
Has anyone seen an issue like this before -- where IE snaps back to the top of the page after interacting with a drag and drop element, causing the element to move out of the viewport?
Some code:
<!-- language: lang-html -->
<div id="rateEditor" class="rateEditorCL">
<fieldset>
<legend>Available Calling Plans</legend>
<ul id="inactiveProductList" class="ratePlanList ui-sortable" unselectable="on" style="-moz-user-select: none;">
<li class="ratePlan" data-planid="7">Africa</li>
<li class="ratePlan" data-planid="5">India</li>
</ul>
</fieldset>
<fieldset>
<legend>Assigned Calling Plans</legend>
<ul id="activeProductList" class="ratePlanList ui-sortable" unselectable="on" style="-moz-user-select: none;">
<li class="ratePlan" data-planid="1" style="">Mexico</li>
<li class="ratePlan" data-planid="3" style="">Asia</li>
</ul>
</fieldset>
</div>
And the jquery:
<!-- language: lang-js -->
// create a sortable, exchangable list of the Available and Active Rate plan lists.
$('#inactiveProductList, #activeProductList').sortable({
// connect the lists by the ratePlanList class
connectWith: ".ratePlanList",
// contain the drag/drop to the wrapper div
containment: '#rateEditor',
// when a list recieves a new item, spin the elements into
// arrays and send them off to our ajax updater function.
receive:function(event,ui) {
activeRates = new Array();
inactiveRates = new Array();
dId = $("#distributorId").val();
uId = $("#activeUserId").val();
$('#activeProductList li').each(function(i) {
activeRates[i] = $(this).attr('data-planID');
});
$('#inactiveProductList li').each(function(i) {
inactiveRates[i] = $(this).attr('data-planID');
});
updateAvailableRatePlans(activeRates,inactiveRates,dId,uId);
}
}).disableSelection();
});
And CSS (just for good measure):
#rateEditor {
float: left;
margin: auto;
text-align: center !important;
width: 100%;
}
.rateEditorCL {
border-left: medium none;
border-right: medium none;
border-top: medium none;
display: block;
float: left;
margin: auto;
padding: 1em;
text-align: center;
width: 100%;
}
Thanks community!
I ended up (hack)fixing this myself by doing two things. It turns out that IE was rendering my div at the bottom of the viewport, and not in its position relative to the page itself. I still don't know how to fix the underlying problem of how IE renders html elements. First, I added a "position: relative" assignment for the container div (#rateEditor).
I also added the following code for detecting IE. It is the same as the code above with a few small differences. Namely, the containment was expanded to body, and the div height was set to expand to the document height on click:
if ( $.browser.msie ) {
$("#inactiveProductList, #activeProductList").sortable({
// connect the lists by the ratePlanList class
connectWith: ".ratePlanList",
// contain the drag/drop to the wrapper div
containment: "body",
//prevents the window from following the cursor when the element is dragged
scroll: false,
// when a list recieves a new item, spin the elements into
// arrays and send them off to our ajax updater function.
receive:function(event,ui) {
activeRates = new Array();
inactiveRates = new Array();
dId = $("#distributorId").val();
uId = $("#activeUserId").val();
$('#activeProductList li').each(function(i) {
activeRates[i] = $(this).attr('data-planID');
});
$('#inactiveProductList li').each(function(i) {
inactiveRates[i] = $(this).attr('data-planID');
});
updateAvailableRatePlans(activeRates,inactiveRates,dId,uId);
}
}).disableSelection();
$("div").rateEditorCL('click', function () {
$(this).height(document)
});
}
I am sure there are more elegant solutions for this issue and welcome feedback from anyone who knows any better.
精彩评论