I'm creating a feature in my software that allows users to edit multiple items at once. They can choose what items they want and each one is placed in a column. I've then created a drag and drop interface to copy data from each item.
Problem is, I have to load a sortable for each column. If they choose 10 columns, it loads a heck of a lot of sortables which is causing the browser to hang and bring up a message in FireFox asking if I want to stop the script from running. This is obviously because browsers have a limited javascript execution time.
Is there a way I can make jQuery sortables load without causing the browser to hang?
Not sure if it'll help but my code...
<script type="text/javascript">
$(document).ready(function() {
$(".servicesMultipleMembers").sortable({
connectWith: '.servicesMultipleMembers',
placeholder: 'servicePlaceHolder',
containment: '#servicesMembers',
helper: 'clone',
start: function(event, ui) {
moving_li_index_members = $(this).find('li:hidden').index();
$(this).find('li:hidden').show();
},
remove: function(event, ui) {
var newRow = $(ui.item).html();
var newRowRel = $(ui.item).attr('memberId');
var newRowTarget = $(event.target).find('li:eq(' + (moving_li_index_members) + ')');
if ($(newRowTarget).length == 0) {
$(event.target).append('<li memberId="' + newRowRel + '">' + newRow + '</li>');
} else {
newRowTarget.before('<li memberId="' + newRowRel + '">' + newRow + '</li>');
}
},
receive: function(event, ui) {
var newRowImg = $(ui.item).find('span.serviceTitle img').attr('src');
var newRow = $(ui.item).html();
newRow = newRow.replace(newRowImg, site_url + 'img/help.png');
newRow = newRow.replace('<span class="member_declined">', '<span class="">');
$(ui.item).html(newRow);
MultipleServices.checkServicesMembersConflicts($(ui.item));
update_member_stop = true;
},
update: function(event, ui) { // Only update if reordering list
if (!update_member_stop && $(event.target).attr('id') == $(ui.item).parent().attr('id'))
MultipleServices.updateServiceMembers开发者_如何学Go($(ui.item).parent());
update_member_stop = false;
}
});
});
</script>
i would try doing something with setTimeout and a recursive function. maybe something like this:
function initSortable(idx) {
if ($(".servicesMultipleMembers").eq(idx).length >0) {
$(".servicesMultipleMembers").eq(idx).sortable({
connectWith: '.servicesMultipleMembers',
placeholder: 'servicePlaceHolder',
containment: '#servicesMembers',
helper: 'clone',
start: function(event, ui) {
moving_li_index_members = $(this).find('li:hidden').index();
$(this).find('li:hidden').show();
},
remove: function(event, ui) {
var newRow = $(ui.item).html();
var newRowRel = $(ui.item).attr('memberId');
var newRowTarget = $(event.target).find('li:eq(' + (moving_li_index_members) + ')');
if ($(newRowTarget).length == 0) {
$(event.target).append('<li memberId="' + newRowRel + '">' + newRow + '</li>');
} else {
newRowTarget.before('<li memberId="' + newRowRel + '">' + newRow + '</li>');
}
},
receive: function(event, ui) {
var newRowImg = $(ui.item).find('span.serviceTitle img').attr('src');
var newRow = $(ui.item).html();
newRow = newRow.replace(newRowImg, site_url + 'img/help.png');
newRow = newRow.replace('<span class="member_declined">', '<span class="">');
$(ui.item).html(newRow);
MultipleServices.checkServicesMembersConflicts($(ui.item));
update_member_stop = true;
},
update: function(event, ui) { // Only update if reordering list
if (!update_member_stop && $(event.target).attr('id') == $(ui.item).parent().attr('id'))
MultipleServices.updateServiceMembers($(ui.item).parent());
update_member_stop = false;
}
});
setTimeout(initSortable(idx+1),500);
} else {
//remove loading message logic goes here
}
}
and then in the document .ready event: initSortable(0);
the set timeout should give the browser some breathing room, though you will probably want some indication of work in progress on the page.
精彩评论