最近工作中用到了jQuery UI中排序和拖拽功能,花了大概一天的時間,搞清楚了大概的參數配置,以及遇到的一些問題,總結如下。 sortable 簡單的配置如下: $('#subs-box').sortable({ axis: 'y', cursor: 'ns-resize', placeholde ...
最近工作中用到了jQuery UI中排序和拖拽功能,花了大概一天的時間,搞清楚了大概的參數配置,以及遇到的一些問題,總結如下。
sortable
簡單的配置如下:
$('#subs-box').sortable({
axis: 'y',
cursor: 'ns-resize',
placeholder: "ui-state-highlight", // 排序過程中占位符的class樣式設置
forcePlaceholderSize: true, // 強迫占位符有一個尺寸大小。
handle:'.sort-at', // 在對象內指定的元素上開始拖動,而不是整個元素都可以拖動
distance: 10,
opacity: 0.8,
containment:'parent', // 元素可以拖動排序的範圍
// helper: 'clone', // 是否clone一個元素進行拖動
items: '.subject', // 指定哪些元素可以排序
stop: function (e, ui) {
// 排序後元素的順序(前提每個元素都需要有id屬性)
let newSubArr = $("#subs-box").sortable('toArray');
console.log(newSubArr);
},
}).disableSelection(); // 拖動時禁止選中元素
還有一些排序時候的事件和方法,都在參考鏈接的文檔裡面。
draggable
dragInit() {
let me = this;
let selector = '.ptype-'+me.selectedSubType;
// 題目拖動
$('#subs-box .subject').draggable({
// appendTo: ".ptype-item.radio", // 當進行拖動時,拖動組件助手應該被添加到的元素。
// connectToSortable: "#subs-box", // 允許draggable被拖拽到指定的sortables中。
// 拖動時使用的是clone的元素。如果值設置為"clone", 那麼該元素將會被覆制,並且被覆制的元素將被拖動。
// 之所以不使用 helper: 'clone', 是因為clone的元素沒有樣式,所以我們需要自定義樣式,所以使用了自定義函數。
helper: function() {
let helper = $(this).clone();
helper.css({'width': $(this).width(), 'background': '#fff'}); // 設置clone元素的樣式
return helper;
},
handle: ".drag-at", // 指定在特定的元素上觸發滑鼠按下事件時,才可以拖動。
cursor: 'move',
// containment: '.sub-box', // 可以限制draggable只能在指定的元素或區域的邊界以內進行拖動。
revert: 'invalid', // 如果設置為true,當拖動停止時,元素位置將被重置。
revertDuration: 200,
distance: 10,
opacity: 0.8,
zIndex: 10000,
refreshPositions: true, // 所有的可拖動位置在每次滑鼠移動時都會被計算。(設置該值使得drop的位置更加精確)
start(event, ui) {
$(selector).addClass('allow'); // 元素拖拽的時候,設置可放置元素的樣式,示意你可以拖拽到那裡去
// 開始拖拽的時候,初始化drop
me.$nextTick(()=>{
me.dropInit();
});
},
stop(event, ui) {
$(selector).removeClass('allow');
// 拖拽停止的時候,銷毀drop函數。
me.dropDestory();
}
}).disableSelection();
},
註意事項:
每次dropInit函數初始化後,如果需要再次初始化,需要先銷毀之前的放置對象。否則第一次初始化後,比如某個地方A可以放置拖拽的元素,但是第二次初始化後,地方A就不可以放置了。然而實際上,如果你不把第一次初始化的dropInit函數銷毀掉,地方A在第二次初始化後還是可以放置的。所以需要在拖拽停止的時候,銷毀上一次的dropInit對象。
dropable
dropInit() {
let me = this;
// 題目放置(設置題目根據不同類型可以放置不同的分頁)
// selector是可變的,也就是每次可拖拽元素可放置的元素是不同的。所以需要每次拖拽後清除之前dropInit對象。
let selector = '.ptype-'+me.selectedSubType;
$(selector).droppable({
// accept: selector,
// accept: function(d) {
// if($(this).hasClass('ptype'+me.selectedSubType)){
// console.log('d>>>>>>',$(this)[0]);
// return true;
// }
// },
// hoverClass: "drop-hover",
tolerance: 'pointer', // 指定使用那種模式來測試一個拖動(draggable)元素"經過"一個放置(droppable)對象
drop: function( event, ui ) {
// $(this) 填充到的元素
// ui.draggable.context 填充的元素
let dragId = $(ui.draggable.context).attr('id');
let dropId = $(this).attr('id');
// 移動到新的分頁
if(dropId === 'newpage') {
me.moveAddPage(dragId);
} else { // 移動題目到另一個分頁
if(dropId === me.selectedPage.id) { // 移動到自己的分組,不做處理
} else {
let index = me.selectedPage.subs.indexOf(dragId);
if(index > -1) {
me.selectedPage.subs.splice(index, 1);
me.pages.forEach(page=>{
if(page.id === dropId) {
page.subs.push(dragId);
}
});
me.$openNotice('移動成功');
// 其他操作...
}
}
}
$(this).removeClass('allow-hover');
},
over(event, ui) {
$(this).addClass('allow-hover'); // 當拖拽元素進入可放元素時,可放置元素本身的樣式
},
out() {
$(this).removeClass('allow-hover'); // 設置拖拽元素離開可放元素時,清除可放置元素本身的樣式
}
});
},
dropDestory() {
let selector = '.ptype-'+me.selectedSubType;
$(selector).droppable("destroy");
},
參考鏈接
- https://www.html.cn/jquery-ui-api/sortable/
- https://www.html.cn/jquery-ui-api/draggable/
- https://www.html.cn/jquery-ui-api/droppable