一. Html5的拖拽行爲javascript
1.設置元素爲可拖放:把draggable屬性設置爲true.css
example: <div id="drag1" draggable="true"></div>html
(注:img和帶href的a默認是auto,表示可拖拽,其餘的元素都是不可拖拽。爲安全起見,建議對可拖拽元素都添加draggable='true'設置)java
2.拖拽元素事件:angularjs
1). dragstart:拖拽前觸發,即鼠標按下,被拖拽元素被拖拽的瞬間觸發。瀏覽器
event.dataTransfer:傳遞數據,數據類型爲字符串和文件類型。安全
event.dataTransfer的大部分設置均在這裏配置,即經過event.dataTransfer來保存拖拽的數據,例如:e.dataTransfer.setData("Text", e.target.id);ruby
event.dataTransfer.effectAllowed:用於設置被拖拽元素可執行的操做app
example:event.dataTransfer.effectAllowed = "link"; 限定dropEffect的屬性值爲link,不然會鼠標指針爲禁止樣式spa
觸發dragstart事件後,其餘元素的mousemove,mouseover,mouseenter,mouseleave,mouseout事件均不會被觸發了
2). drag:拖拽前、拖拽結束之間連續觸發,即便鼠標沒有移動,只要未釋放,都會觸發。
3). dragend:拖拽結束觸發,即釋放鼠標觸發。
3.目標元素事件:
1). dragenter:進入目標元素觸發,至關於mouseover
2). dragover:被拖拽元素在目標元素上移動時觸發,至關於mousemove
在該事件裏填寫: event.preventDefault() 。
(注:事件的默認行爲是不容許被拖拽元素在其餘元素上釋放或放置(即沒法觸發 drop 事件),須要經過 event.preventDefault() 來阻止默認行爲才能觸發後續的 drop 事件)
dropEffect:拖放的操做類型,決定了瀏覽器如何顯示鼠標形狀,可能的值爲copy、move、link和none。
能夠在這裏設置dropEffect的值,事件的默認行爲是將dropEffect設置爲none。
例如:e.dataTransfer.dropEffect = "link"
3). dragleave:被拖拽元素離開目標元素時觸發
4). drop:被拖拽元素放置在目標元素上時觸發(釋放鼠標)
(注:對於外來的被拖拽元素(超連接、文件、圖片源), drop 事件的默認行爲是瀏覽器將當前頁面重定向到被拖拽元素所指向的資源上
對文檔內部的被拖拽元素,IE10+和Chrome下的默認行爲是不做爲,而FF得默認行爲是新打開一個文檔用於訪問被拖拽元素所指向的資源)
4.事件執行順序
1) drop不觸發的時候:dragstart > drag > dragenter > dragover > dragleave > dragend
2) drop觸發的時候(dragover阻止了默認事件):dragstart > drag > dragenter > dragover > drop > dragend
二:拖拽事件和Angular JS的結合
html
<!DocType html> <html data-ng-app="myApp"> <head> <title>angularjs 和拖拽事件的結合</title> <meta charset="utf-8" /> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript" src="dragdirective.js"></script> <script type="text/javascript" src="mydrag.js"></script> <style type="text/css"> .mydemo > div { display: inline-block; } .mydemo > div > div { width: 150px; height: 100px; border: 1px dotted grey; display: inline-block; float: left; margin-right: 20px; } </style> </head> <body data-ng-controller="myDragController as vm" class="mydemo"> <div> <div ruby-drop="vm.drop(event)" ruby-dragover="vm.dragover(event)"> <img src="ruby.png" draggable="true" ruby-dragstart="vm.dragstart(event)" id="imgId" /> </div> <div ruby-drop="vm.drop(event)" ruby-dragover="vm.dragover(event)"></div> </div> </body> </html>
js->dragdirective.js
(function () { "use strict" var convertFirstUpperCase = function (str) { return str.replace(/(\w)/, function (s) { return s.toUpperCase(); }); } angular.module("myApp", []); var myApp = angular.module("myApp"), rubyDragEventDirectives = {}; angular.forEach("dragstart drag dragenter dragover drop dragleave dragend".split(' '), function (eventName) { var rubyEventName = 'ruby' + convertFirstUpperCase(eventName); rubyDragEventDirectives[rubyEventName] = ['$parse', function ($parse) { //$parse 語句解析器 return { restrict: 'A', compile: function (ele, attr) { var fn = $parse(attr[rubyEventName]); return function rubyEventHandler(scope, ele) { ele[0].addEventListener(eventName, function (event) { if (eventName == 'dragover' || eventName == 'drop') { event.preventDefault(); } var callback = function () { fn(scope, { event: event }); }; callback(); }); } } } }] }); myApp.directive(rubyDragEventDirectives); })();
js->mydrag.js
(function () { "use strict" if (window.angular) { angular.module("myApp").controller("myDragController", myDragController); myDragController.$inject = ['$scope']; function myDragController($scope) { $scope.vm.dragstart = function (e) { e.dataTransfer.setData("Text", e.target.id); }; $scope.vm.dragover = function (e) { e.preventDefault(); }; $scope.vm.drop = function (e) { e.preventDefault(); var data = e.dataTransfer.getData("Text"); e.target.appendChild(document.getElementById(data)); }; } } })();