jQuery ui中sortable draggable droppable的使用
阿新 • • 發佈:2020-07-23
最近工作中用到了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"); },