1. 程式人生 > >結合AngularJS實現拖拽

結合AngularJS實現拖拽

per sta html 行為 FN ruby pre js實現 gin

最近項目中要實現,左側樹向右側樹中元素的拖拽功能,開始在網上看了好多ng-drag等等操作,都沒有實現預想的效果,偶然發現一篇博客,然後根據博客改編,實現了自己想要的效果。下面簡單的分析一下實現過程。首先我先附上源碼,如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <title>test</title>
  7     <script src="angular.min.js"
></script> 8 <style> 9 ul { 10 padding: 0; 11 margin: 0; 12 width: 300px; 13 } 14 15 .left { 16 float: left; 17 background-color: #ddd; 18 margin-left: 300px; 19 } 20 21 .right { 22 float: right;
23 background-color: #aaa; 24 margin-right: 300px; 25 } 26 27 li { 28 line-height: 30px; 29 } 30 31 .left li:hover { 32 background-color: orange; 33 cursor: move; 34 } 35 36 .right li:hover { 37 background-color: red
; 38 cursor: move; 39 } 40 </style> 41 </head> 42 43 <body ng-app="myApp" ng-controller="MyCtrl"> 44 <ul class="left"> 45 <li ng-repeat="item in dogs" draggable="true" ruby-dragstart="dragstart(item)">{{ item.name }}</li> 46 </ul> 47 <ul class="right"> 48 <li ng-repeat="item in cats" ruby-drop="drop(event,item)" ruby-dragover="dragover(event)">{{ item.name }}</li> 49 </ul> 50 <script> 51 var app = angular.module(myApp, []); 52 app.controller(MyCtrl, [$scope, function($scope) { 53 $scope.dogs = [ 54 { id: 1, name: 大狗 }, 55 { id: 2, name: 二狗 }, 56 { id: 3, name: 三狗 }, 57 { id: 4, name: 四狗 } 58 ]; 59 $scope.cats = [ 60 { id: 11, name: 大貓 }, 61 { id: 12, name: 二貓 }, 62 { id: 13, name: 三貓 }, 63 { id: 14, name: 四貓 } 64 ]; 65 $scope.dragover = function(event) { 66 event.preventDefault(); 67 } 68 $scope.dragstart = function(item) { 69 $scope.clientInfo = item; 70 } 71 $scope.drop = function(event, item) { 72 event.preventDefault(); 73 console.log("dog:->", $scope.clientInfo); 74 console.log("cat:->", item); 75 } 76 }]); 77 var convertFirstUpperCase = function(str) { 78 return str.replace(/(\w)/, function(s) { 79 return s.toUpperCase(); 80 }); 81 }; 82 rubyDragEventDirectives = {}; 83 angular.forEach("dragstart drag dragenter dragover drop dragleave dragend".split( ), function(eventName) { 84 var rubyEventName = ruby + convertFirstUpperCase(eventName); 85 rubyDragEventDirectives[rubyEventName] = [$parse, function($parse) { 86 //$parse 語句解析器 87 return { 88 restrict: A, 89 compile: function(ele, attr) { 90 var fn = $parse(attr[rubyEventName]); 91 return function rubyEventHandler(scope, ele) { 92 ele[0].addEventListener(eventName, function(event) { 93 if (eventName == dragover || eventName == drop) { 94 event.preventDefault(); 95 } 96 var callback = function() { 97 fn(scope, { event: event }); 98 }; 99 callback(); 100 }); 101 } 102 } 103 } 104 }] 105 }); 106 app.directive(rubyDragEventDirectives); 107 </script> 108 </body> 109 110 </html>

為了簡便,我把整個html,css以及js寫在一個文件了,如果是真實項目中,最好將其分開。其實大家可以發現,html中僅僅只是加入了自定義指令

ruby-dragstart,開始拖動,可以檢測到開始拖動的整個event及DOM元素;
ruby-dragover,當某被拖動的對象在另一對象容器範圍內拖動時觸發此事件.在該事件裏填寫: event.preventDefault() 。註:事件的默認行為是不允許被拖拽元素在其他元素上釋放或放置(即無法觸發 drop 事件),需要通過 event.preventDefault() 來阻止默認行為才能觸發後續的 drop 事件)
ruby-drop,拖動的目標元素,當你拖動結束,會檢測到是在哪個DOM元素上結束的拖拽事件;
draggable="true" ,是允許拖動,加上之後,拖動的時候會顯示一個加號。
CSS這裏就不再贅述了,大家想怎麽玩就怎麽玩,還要註意的一點就是自定義指令rubyDragEventDirectives,在自定義模塊中,convertFirstUpperCase是為入參做一個合理接收,熟悉JS的朋友應該很快能夠理解的。總結下來,這個實現也不是太難,對吧?我們一起去探索吧。。。

結合AngularJS實現拖拽