項目需要,實現一個拖放操作,要求每次可以拖拽選中的多個元素,釋放到目標容器後可排序。考慮了一下,覺得jquery-ui比較合適,畢竟它提供了項目需要的交互性事件機制。拖拽、釋放、排序、選擇等效果。而在實際的操作中,遇到個很多的問題,說明一下,最後附上效果圖和代碼。
1.本人使用的bootstrap框架,引入jquery-ui後,為元素添加拖拽方法後,提示該方法不是一個函數。查找原因,是bootstrap和jquery-uide的$ 標識符控制權沖突。在引入的jquery-ui的js前加上一下語句解決
<script> jQuery.noConflict(); </script>
2.jquery-ui的提供了選擇操作(單選,多選),其中多選可以按住Ctrl配合鼠標單擊多選,也可以鼠標在多個元素上拖拽進行多選。在為同一元素添加上選擇操作和拖拽操作時,出現了問題。
a:多選的操作由於可以在元素上拖拽,與本身的拖拽事件有沖突(個人認為鼠標拖拽多選的效果並沒有使用shift配合鼠標點擊好用)。
b:jquery-ui沒有發現可以將多個單獨的元素同時拖拽。
不知道是本人愚鈍沒有發現jquery-ui可以使用本身自帶的方法和屬性,即可以支持多選又能拖拽選中的元素操作。哪位讀者如果知曉還請告知。3Q!
總之,試驗了多個jquery-ui的屬性和事件,有去試著將jquery-ui的拖拽多選操作刪除,也沒有發現我需要的效果。所以,考慮了一下,決定不適用jquery-ui的選擇操作。自己來寫一個選擇操作。與我們平常使用的事件觸發機制一樣。(鼠標單擊單選,Ctrl+鼠標多選,Shift+鼠標多選),然後配合jquery-ui的drag和drop和sort事件機制實現拖拽排序效果。
再插一嘴,拖拽多個元素的效果,實際上是拖拽一個指定的dom元素,可以將需要拖拽的所有節點都放置到該元素中。這個需要配合jquery-ui的drag中的helper函數,返回一個新的拖拽元素集合。(關於jquery-ui的一些事件和屬性大家可從網上查閱。不過說得也不盡詳細,還需要自己去實驗)。
Okay,貼出簡單的效果圖和代碼
圖一(拖放中效果)
圖二(釋放後效果)
效果圖如上,左側橙色為選中的節點,紅色橢圓內部為鼠標拖拽的效果,3表示選中的元素呢個數;右側的黃色區域表示可以釋放和排序的容器。在該區域拖放時,節點會根據鼠標的位置自動排序,如圖,如果釋放鼠標後,左側的3個節點就會移動到4.對應的黃色區域。
當然,以上的效果需要去重新給拖拽目標賦予新的元素,並且監聽拖拽,釋放等時間,編寫用戶自定義的邏輯。貼出自己的代碼,一些事件和屬性可以查閱jquery-ui的文檔。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="assets/css/bootstrap.css" /> <link rel="stylesheet" href="js/jquery-ui-1.12.1.dropable/jquery-ui.css" /> <script src="js/jquery-1.11.2.js"></script> <script src="assets/js/bootstrap.js"/> <script> jQuery.noConflict(); //解決jQuery控制權沖突問題 </script> <script src="js/jquery-ui-1.12.1.dropable/jquery-ui.js"></script> <style> .selectable .ui-selecting{ background: #FECA40; } .selectable .ui-selected{ background: #F39814; color: white; } .selectable{ list-style-type: none; margin: 0; padding: 0; width: 80%; } .selectable li{ list-style: none; margin: 3px; padding: 0.4em; font-size: 1.4em; height: 32px;moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-select:none; -webkit-user-select:none; -ms-user-select:none; user-select:none; } .drag_info_box{ width:40px; height:40px; text-align: center; font-size:14px; line-height: 40px; background: #21aeff; color:#000000; } </style> <script> $(function(){ //自定義多選方法 var selected_begin_index,selected_end_index; $("#mydrag").on("mousedown",".selectable>li",function(e){ var _selectable= $(this).parent(); if(!e.ctrlKey && !e.shiftKey){ //沒有按下Ctrl或Shift鍵 if(!$(this).hasClass("ui-selected")){ _selectable.children("li").removeClass("ui-selected"); } $(this).addClass("ui-selected"); selected_begin_index=_selectable.children("li").index(this); }else if(e.ctrlKey && !e.shiftKey){ //只按下Ctrl鍵 $(this).addClass("ui-selected"); selected_begin_index=_selectable.children("li").index(this); }else if((!e.ctrlKey && e.shiftKey) || (e.ctrlKey && e.shiftKey)){ //只按下Shift鍵或Ctrl和Shift鍵都按下 _selectable.children("li").removeClass("ui-selected"); $(this).addClass("ui-selected"); if(selected_begin_index!=undefined){ selected_end_index=_selectable.children("li").index(this); }else{ selected_begin_index=_selectable.children("li").index(this); } if(selected_end_index>=selected_begin_index){ for(var i=selected_begin_index;i<=selected_end_index;i++){ _selectable.children("li").eq(i).addClass("ui-selected"); } }else{ for(var i=selected_end_index;i<=selected_begin_index;i++){ _selectable.children("li").eq(i).addClass("ui-selected"); } } } }).on("mouseup",".selectable>li",function(e){ var _selectable= $(this).parent(); if(!e.ctrlKey && !e.shiftKey){ //沒有按下Ctrl或Shift鍵 _selectable.children("li").removeClass("ui-selected"); $(this).addClass("ui-selected"); } }); //調用拖拽事件並重新規劃處理方式 $("#mydrag .selectable>li").draggable({ revert: "invalid", containment: "document", cursor: "default", distance:10, zIndex:9, opacity:0.5, cursorAt: { left: 20, top:40 }, connectToSortable:"#mydrag .sample-group>ol", helper:function(event,ui){ var drag_info_box=$("<div></div>").addClass("drag_info_box"); drag_info_box.append($("<span></span>")); drag_info_box.append($('<input type="hidden" />')); return drag_info_box; }, start: function( event, ui ) { var _drag_ele=ui.helper; _drag_ele.children("span").eq(0).text($("#mydrag .selectable>li.ui-selected").length); var selected_li_seq=""; $("#mydrag .selectable>li.ui-selected").each(function(){ selected_li_seq+= $("#mydrag .selectable>li").index(this)+","; }); _drag_ele.children("input").eq(0).val(selected_li_seq.substr(0,selected_li_seq.length-1)); }, stop:function( event, ui ) { $(".selectable li").removeClass("ui-selected"); } }); $("#mydrag .sample-group>ol").droppable({ activeClass: "ui-state-highlight", drop: function( event, ui ) { //這塊如果是拖放到排序面板會執行兩次,將該內容放到排序的stop方法中 } }); //排序完畢後執行真正的釋放操作 $( "#mydrag .sample-group>ol" ).sortable({ revert: true, stop: function( event, ui ) { if(ui.item.hasClass("drag_info_box")){ var selected_li_arr=ui.item.children("input").eq(0).val().split(','); for(var i=0;i<selected_li_arr.length;i++){ var _group_li_=$("<li></li>") .addClass("ui-state-highlight ui-sortable-handle").text($("#mydrag .selectable>li").eq(selected_li_arr[i]).text()); //為該元素打上上傳標簽 $("#mydrag .selectable>li").eq(selected_li_arr[i]).addClass("delete_flag") $( ".drag_info_box").before(_group_li_); } } $("#mydrag .selectable>li.delete_flag").remove(); $(".drag_info_box").remove(); $(this).sortable(); } }).disableSelection(); }); </script> </head> <body> <div id="mydrag" style="width:1200px;height: auto;"> <div class="col-sm-4" style="background: #eeeeee"> <ol class="selectable"> <li class="ui-widget-content">Item 1</li> <li class="ui-widget-content">Item 2</li> <li class="ui-widget-content">Item 3</li> <li class="ui-widget-content">Item 4</li> <li class="ui-widget-content">Item 5</li> <li class="ui-widget-content">Item 6</li> <li class="ui-widget-content">Item 7</li> </ol> </div> <div class="col-sm-4" style="background: greenyellow"> <div class="sample-groups"> <div class="sample-group" style="min-height: 80px;"> <ol> <li class="ui-state-highlight">Item 1</li> <li class="ui-state-highlight">Item 2</li> <li class="ui-state-highlight">Item 3</li> <li class="ui-state-highlight">Item 4</li> <li class="ui-state-highlight">Item 5</li> </ol> </div> </div> </div> <div class="col-sm-4" style="background: green"> <div class="row"> <div style="background: #ffff00"></div> <div class="col-sm-5" style="background: blue"></div> <div class="col-sm-2" style="background: red"></div> <div class="col-sm-5" style="background: purple"></div> </div> </div> </div> </body> </html>
代碼可用(沒有寫單選的釋放效果,例子是目前的一個試驗品,後續還要改成插件方式)。記錄一下這兩天的心得。主要是查找事件機制,整理思路和處理沖突問題花費了一定精力,得記上一筆。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。