最近項目中要實現,左側樹向右側樹中元素的拖拽功能,開始在網上看了好多ng-drag等等操做,都沒有實現預想的效果,偶然發現一篇博客,而後根據博客改編,實現了本身想要的效果。下面簡單的分析一下實現過程。首先我先附上源碼,以下:css
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中僅僅只是加入了自定義指令html
ruby-dragstart,開始拖動,能夠檢測到開始拖動的整個event及DOM元素;
ruby-dragover,當某被拖動的對象在另外一對象容器範圍內拖動時觸發此事件.在該事件裏填寫: event.preventDefault() 。注:事件的默認行爲是不容許被拖拽元素在其餘元素上釋放或放置(即沒法觸發 drop 事件),須要經過 event.preventDefault() 來阻止默認行爲才能觸發後續的 drop 事件)
ruby-drop,拖動的目標元素,當你拖動結束,會檢測到是在哪一個DOM元素上結束的拖拽事件;
draggable="true" ,是容許拖動,加上以後,拖動的時候會顯示一個加號。CSS這裏就再也不贅述了,你們想怎麼玩就怎麼玩,還要注意的一點就是自定義指令rubyDragEventDirectives,在自定義模塊中,convertFirstUpperCase是爲入參作一個合理接收,熟悉JS的朋友應該很快可以理解的。總結下來,這個實現也不是太難,對吧?咱們一塊兒去探索吧。。。