1.相关地址:

插件下载:https://github.com/fatlinesofcode/ngDraggable/blob/master/ngDraggable.js

data-drag形式没用过,但找到了两个相关链接
http://codef0rmer.github.io/angular-dragdrop/#!/#%2F
http://benohead.com/drag-drop-with-angularjs/

2.讲解

<div ng-drop="true" ng-drop-success="dropComplete($index,$data,$event)" ng-repeat="item in content"><li ng-drag="true" ng-drag-data="item" >姓名:{{item.name}},年龄:{{item.age}}</li>
</div>

ng-drag : 表示该元素能够被拖动
ng-drag-data : 表示拖动元素时跟着被拖走的数据

ng-drop : 表示该元素内可放置被拖动的元素
ng-drop-success : 放置在ngd-drop所在元素里后触发,一般写事件.

ng-drop-success触发的dropComplete方法的参数说明
$index : 表示拖动的数据所落的元素的下标
$data : 被拖动的数据对象

3.拖拽排序示例

页面代码

<div ng-drop="true" ng-drop-success="dropComplete($index,$data)" ng-repeat="item in content"><li ng-drag="true" ng-drag-data="item" >姓名:{{item.name}},年龄:{{item.age}}</li>
</div>

JS代码

//数据
$scope.content = [{'name':'张春玲','age':28},{'name':'王晰','age':26},{'name':'吴正青','age':66}];/** 拖拽成功触发方法
*   index 拖拽后落下时的元素的序号(下标)
*   obj被拖动数据对象
*/
$scope.dropComplete = function(index, obj){//重新排序var idx = $scope.content.indexOf(obj);             $scope.content.splice(idx,1);$scope.content.splice(index,0,obj);   };

4.拖拽交换示例

页面代码

<div ng-drop="true" ng-drop-success="dropComplete($index,$data)" ng-repeat="item in content"><li ng-drag="true" ng-drag-data="item" >姓名:{{item.name}},年龄:{{item.age}}</li>
</div>

JS代码

//数据
$scope.content = [{'name':'张春玲','age':28},{'name':'王晰','age':26},{'name':'吴正青','age':66}];/** 拖拽成功触发方法
*   index 拖拽后落下时的元素的序号(下标)
*   obj 被拖动数据对象
*/
$scope.dropComplete = function(index, obj){var idx = $scope.content.indexOf(obj); $scope.content[idx] = $scope.content[index];$scope.content[index] = obj;
};

5. ngDraggable插件代码

/*** https://github.com/fatlinesofcode/ngDraggable*/
angular.module("ngDraggable", []).service('ngDraggable', [function() {var scope = this;scope.inputEvent = function(event) {if (angular.isDefined(event.touches)) {return event.touches[0];}//Checking both is not redundent. If only check if touches isDefined, angularjs isDefnied will return error and stop the remaining scripty if event.originalEvent is not defined.else if (angular.isDefined(event.originalEvent) && angular.isDefined(event.originalEvent.touches)) {return event.originalEvent.touches[0];}return event;};}]).directive('ngDrag', ['$rootScope', '$parse', '$document', '$window', 'ngDraggable', function ($rootScope, $parse, $document, $window, ngDraggable) {return {restrict: 'A',link: function (scope, element, attrs) {scope.value = attrs.ngDrag;var offset,_centerAnchor=false,_mx,_my,_tx,_ty,_mrx,_mry;var _hasTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;var _pressEvents = 'touchstart mousedown';var _moveEvents = 'touchmove mousemove';var _releaseEvents = 'touchend mouseup';var _dragHandle;// to identify the element in order to prevent getting superflous events when a single element has both drag and drop directives on it.var _myid = scope.$id;var _data = null;var _dragOffset = null;var _dragEnabled = false;var _pressTimer = null;var onDragStartCallback = $parse(attrs.ngDragStart) || null;var onDragStopCallback = $parse(attrs.ngDragStop) || null;var onDragSuccessCallback = $parse(attrs.ngDragSuccess) || null;var allowTransform = angular.isDefined(attrs.allowTransform) ? scope.$eval(attrs.allowTransform) : true;var getDragData = $parse(attrs.ngDragData);// deregistration function for mouse move events in $rootScope triggered by jqLite trigger handlervar _deregisterRootMoveListener = angular.noop;var initialize = function () {element.attr('draggable', 'false'); // prevent native drag// check to see if drag handle(s) was specified// if querySelectorAll is available, we use this instead of find// as JQLite find is limited to tagnamesif (element[0].querySelectorAll) {var dragHandles = angular.element(element[0].querySelectorAll('[ng-drag-handle]'));} else {var dragHandles = element.find('[ng-drag-handle]');}if (dragHandles.length) {_dragHandle = dragHandles;}toggleListeners(true);};var toggleListeners = function (enable) {if (!enable)return;// add listeners.scope.$on('$destroy', onDestroy);scope.$watch(attrs.ngDrag, onEnableChange);scope.$watch(attrs.ngCenterAnchor, onCenterAnchor);// wire up touch eventsif (_dragHandle) {// handle(s) specified, use those to initiate drag_dragHandle.on(_pressEvents, onpress);} else {// no handle(s) specified, use the element as the handleelement.on(_pressEvents, onpress);}if(! _hasTouch && element[0].nodeName.toLowerCase() == "img"){element.on('mousedown', function(){ return false;}); // prevent native drag for images}};var onDestroy = function (enable) {toggleListeners(false);};var onEnableChange = function (newVal, oldVal) {_dragEnabled = (newVal);};var onCenterAnchor = function (newVal, oldVal) {if(angular.isDefined(newVal))_centerAnchor = (newVal || 'true');};var isClickableElement = function (evt) {return (angular.isDefined(angular.element(evt.target).attr("ng-cancel-drag")));};/** When the element is clicked start the drag behaviour* On touch devices as a small delay so as not to prevent native window scrolling*/var onpress = function(evt) {if(! _dragEnabled)return;if (isClickableElement(evt)) {return;}if (evt.type == "mousedown" && evt.button != 0) {// Do not start dragging on right-clickreturn;}if(_hasTouch){cancelPress();_pressTimer = setTimeout(function(){cancelPress();onlongpress(evt);},100);$document.on(_moveEvents, cancelPress);$document.on(_releaseEvents, cancelPress);}else{onlongpress(evt);}};var cancelPress = function() {clearTimeout(_pressTimer);$document.off(_moveEvents, cancelPress);$document.off(_releaseEvents, cancelPress);};var onlongpress = function(evt) {if(! _dragEnabled)return;evt.preventDefault();offset = element[0].getBoundingClientRect();if(allowTransform)_dragOffset = offset;else{_dragOffset = {left:document.body.scrollLeft, top:document.body.scrollTop};}element.centerX = element[0].offsetWidth / 2;element.centerY = element[0].offsetHeight / 2;_mx = ngDraggable.inputEvent(evt).pageX;//ngDraggable.getEventProp(evt, 'pageX');_my = ngDraggable.inputEvent(evt).pageY;//ngDraggable.getEventProp(evt, 'pageY');_mrx = _mx - offset.left;_mry = _my - offset.top;if (_centerAnchor) {_tx = _mx - element.centerX - $window.pageXOffset;_ty = _my - element.centerY - $window.pageYOffset;} else {_tx = _mx - _mrx - $window.pageXOffset;_ty = _my - _mry - $window.pageYOffset;}$document.on(_moveEvents, onmove);$document.on(_releaseEvents, onrelease);// This event is used to receive manually triggered mouse move events// jqLite unfortunately only supports triggerHandler(...)// See http://api.jquery.com/triggerHandler/// _deregisterRootMoveListener = $rootScope.$on('draggable:_triggerHandlerMove', onmove);_deregisterRootMoveListener = $rootScope.$on('draggable:_triggerHandlerMove', function(event, origEvent) {onmove(origEvent);});};var onmove = function (evt) {if (!_dragEnabled)return;evt.preventDefault();if (!element.hasClass('dragging')) {_data = getDragData(scope);element.addClass('dragging');$rootScope.$broadcast('draggable:start', {x:_mx, y:_my, tx:_tx, ty:_ty, event:evt, element:element, data:_data});if (onDragStartCallback ){scope.$apply(function () {onDragStartCallback(scope, {$data: _data, $event: evt});});}}_mx = ngDraggable.inputEvent(evt).pageX;//ngDraggable.getEventProp(evt, 'pageX');_my = ngDraggable.inputEvent(evt).pageY;//ngDraggable.getEventProp(evt, 'pageY');if (_centerAnchor) {_tx = _mx - element.centerX - _dragOffset.left;_ty = _my - element.centerY - _dragOffset.top;} else {_tx = _mx - _mrx - _dragOffset.left;_ty = _my - _mry - _dragOffset.top;}moveElement(_tx, _ty);$rootScope.$broadcast('draggable:move', { x: _mx, y: _my, tx: _tx, ty: _ty, event: evt, element: element, data: _data, uid: _myid, dragOffset: _dragOffset });};var onrelease = function(evt) {if (!_dragEnabled)return;evt.preventDefault();$rootScope.$broadcast('draggable:end', {x:_mx, y:_my, tx:_tx, ty:_ty, event:evt, element:element, data:_data, callback:onDragComplete, uid: _myid});element.removeClass('dragging');element.parent().find('.drag-enter').removeClass('drag-enter');reset();$document.off(_moveEvents, onmove);$document.off(_releaseEvents, onrelease);if (onDragStopCallback ){scope.$apply(function () {onDragStopCallback(scope, {$data: _data, $event: evt});});}_deregisterRootMoveListener();};var onDragComplete = function(evt) {if (!onDragSuccessCallback )return;scope.$apply(function () {onDragSuccessCallback(scope, {$data: _data, $event: evt});});};var reset = function() {if(allowTransform)element.css({transform:'', 'z-index':'', '-webkit-transform':'', '-ms-transform':''});elseelement.css({'position':'',top:'',left:''});};var moveElement = function (x, y) {if(allowTransform) {element.css({transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', ' + y + ', 0, 1)','z-index': 99999,'-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', ' + y + ', 0, 1)','-ms-transform': 'matrix(1, 0, 0, 1, ' + x + ', ' + y + ')'});}else{element.css({'left':x+'px','top':y+'px', 'position':'fixed'});}};initialize();}};}]).directive('ngDrop', ['$parse', '$timeout', '$window', '$document', 'ngDraggable', function ($parse, $timeout, $window, $document, ngDraggable) {return {restrict: 'A',link: function (scope, element, attrs) {scope.value = attrs.ngDrop;scope.isTouching = false;var _lastDropTouch=null;var _myid = scope.$id;var _dropEnabled=false;var onDropCallback = $parse(attrs.ngDropSuccess);// || function(){};var onDragStartCallback = $parse(attrs.ngDragStart);var onDragStopCallback = $parse(attrs.ngDragStop);var onDragMoveCallback = $parse(attrs.ngDragMove);var initialize = function () {toggleListeners(true);};var toggleListeners = function (enable) {// remove listenersif (!enable)return;// add listeners.scope.$watch(attrs.ngDrop, onEnableChange);scope.$on('$destroy', onDestroy);scope.$on('draggable:start', onDragStart);scope.$on('draggable:move', onDragMove);scope.$on('draggable:end', onDragEnd);};var onDestroy = function (enable) {toggleListeners(false);};var onEnableChange = function (newVal, oldVal) {_dropEnabled=newVal;};var onDragStart = function(evt, obj) {if(! _dropEnabled)return;isTouching(obj.x,obj.y,obj.element);if (attrs.ngDragStart) {$timeout(function(){onDragStartCallback(scope, {$data: obj.data, $event: obj});});}};var onDragMove = function(evt, obj) {if(! _dropEnabled)return;isTouching(obj.x,obj.y,obj.element);if (attrs.ngDragMove) {$timeout(function(){onDragMoveCallback(scope, {$data: obj.data, $event: obj});});}};var onDragEnd = function (evt, obj) {// don't listen to drop events if this is the element being dragged// only update the styles and returnif (!_dropEnabled || _myid === obj.uid) {updateDragStyles(false, obj.element);return;}if (isTouching(obj.x, obj.y, obj.element)) {// call the ngDraggable ngDragSuccess element callbackif(obj.callback){obj.callback(obj);}if (attrs.ngDropSuccess) {$timeout(function(){onDropCallback(scope, {$data: obj.data, $event: obj, $target: scope.$eval(scope.value)});});}}if (attrs.ngDragStop) {$timeout(function(){onDragStopCallback(scope, {$data: obj.data, $event: obj});});}updateDragStyles(false, obj.element);};var isTouching = function(mouseX, mouseY, dragElement) {var touching= hitTest(mouseX, mouseY);scope.isTouching = touching;if(touching){_lastDropTouch = element;}updateDragStyles(touching, dragElement);return touching;};var updateDragStyles = function(touching, dragElement) {if(touching){element.addClass('drag-enter');dragElement.addClass('drag-over');}else if(_lastDropTouch == element){_lastDropTouch=null;element.removeClass('drag-enter');dragElement.removeClass('drag-over');}};var hitTest = function(x, y) {var bounds = element[0].getBoundingClientRect();// ngDraggable.getPrivOffset(element);x -= $document[0].body.scrollLeft + $document[0].documentElement.scrollLeft;y -= $document[0].body.scrollTop + $document[0].documentElement.scrollTop;return  x >= bounds.left&& x <= bounds.right&& y <= bounds.bottom&& y >= bounds.top;};initialize();}};}]).directive('ngDragClone', ['$parse', '$timeout', 'ngDraggable', function ($parse, $timeout, ngDraggable) {return {restrict: 'A',link: function (scope, element, attrs) {var img, _allowClone=true;var _dragOffset = null;scope.clonedData = {};var initialize = function () {img = element.find('img');element.attr('draggable', 'false');img.attr('draggable', 'false');reset();toggleListeners(true);};var toggleListeners = function (enable) {// remove listenersif (!enable)return;// add listeners.scope.$on('draggable:start', onDragStart);scope.$on('draggable:move', onDragMove);scope.$on('draggable:end', onDragEnd);preventContextMenu();};var preventContextMenu = function() {//  element.off('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);img.off('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);//  element.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);img.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);};var onDragStart = function(evt, obj, elm) {_allowClone=true;if(angular.isDefined(obj.data.allowClone)){_allowClone=obj.data.allowClone;}if(_allowClone) {scope.$apply(function () {scope.clonedData = obj.data;});element.css('width', obj.element[0].offsetWidth);element.css('height', obj.element[0].offsetHeight);moveElement(obj.tx, obj.ty);}};var onDragMove = function(evt, obj) {if(_allowClone) {_tx = obj.tx + obj.dragOffset.left;_ty = obj.ty + obj.dragOffset.top;moveElement(_tx, _ty);}};var onDragEnd = function(evt, obj) {//moveElement(obj.tx,obj.ty);if(_allowClone) {reset();}};var reset = function() {element.css({left:0,top:0, position:'fixed', 'z-index':-1, visibility:'hidden'});};var moveElement = function(x,y) {element.css({transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, '+x+', '+y+', 0, 1)', 'z-index': 99999, 'visibility': 'visible','-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, '+x+', '+y+', 0, 1)','-ms-transform': 'matrix(1, 0, 0, 1, '+x+', '+y+')'//,margin: '0'  don't monkey with the margin,});};var absorbEvent_ = function (event) {var e = event;//.originalEvent;e.preventDefault && e.preventDefault();e.stopPropagation && e.stopPropagation();e.cancelBubble = true;e.returnValue = false;return false;};initialize();}};}]).directive('ngPreventDrag', ['$parse', '$timeout', function ($parse, $timeout) {return {restrict: 'A',link: function (scope, element, attrs) {var initialize = function () {element.attr('draggable', 'false');toggleListeners(true);};var toggleListeners = function (enable) {// remove listenersif (!enable)return;// add listeners.element.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);};var absorbEvent_ = function (event) {var e = event.originalEvent;e.preventDefault && e.preventDefault();e.stopPropagation && e.stopPropagation();e.cancelBubble = true;e.returnValue = false;return false;};initialize();}};}]).directive('ngCancelDrag', [function () {return {restrict: 'A',link: function (scope, element, attrs) {element.find('*').attr('ng-cancel-drag', 'ng-cancel-drag');}};}]).directive('ngDragScroll', ['$window', '$interval', '$timeout', '$document', '$rootScope', function($window, $interval, $timeout, $document, $rootScope) {return {restrict: 'A',link: function(scope, element, attrs) {var intervalPromise = null;var lastMouseEvent = null;var config = {verticalScroll: attrs.verticalScroll || true,horizontalScroll: attrs.horizontalScroll || true,activationDistance: attrs.activationDistance || 75,scrollDistance: attrs.scrollDistance || 15};var reqAnimFrame = (function() {return window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {window.setTimeout(callback, 1000 / 60);};})();var animationIsOn = false;var createInterval = function() {animationIsOn = true;function nextFrame(callback) {var args = Array.prototype.slice.call(arguments);if(animationIsOn) {reqAnimFrame(function () {$rootScope.$apply(function () {callback.apply(null, args);nextFrame(callback);});})}}nextFrame(function() {if (!lastMouseEvent) return;var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);var viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);var scrollX = 0;var scrollY = 0;if (config.horizontalScroll) {// If horizontal scrolling is active.if (lastMouseEvent.clientX < config.activationDistance) {// If the mouse is on the left of the viewport within the activation distance.scrollX = -config.scrollDistance;}else if (lastMouseEvent.clientX > viewportWidth - config.activationDistance) {// If the mouse is on the right of the viewport within the activation distance.scrollX = config.scrollDistance;}}if (config.verticalScroll) {// If vertical scrolling is active.if (lastMouseEvent.clientY < config.activationDistance) {// If the mouse is on the top of the viewport within the activation distance.scrollY = -config.scrollDistance;}else if (lastMouseEvent.clientY > viewportHeight - config.activationDistance) {// If the mouse is on the bottom of the viewport within the activation distance.scrollY = config.scrollDistance;}}if (scrollX !== 0 || scrollY !== 0) {// Record the current scroll position.var currentScrollLeft = ($window.pageXOffset || $document[0].documentElement.scrollLeft);var currentScrollTop = ($window.pageYOffset || $document[0].documentElement.scrollTop);// Remove the transformation from the element, scroll the window by the scroll distance// record how far we scrolled, then reapply the element transformation.var elementTransform = element.css('transform');element.css('transform', 'initial');$window.scrollBy(scrollX, scrollY);var horizontalScrollAmount = ($window.pageXOffset || $document[0].documentElement.scrollLeft) - currentScrollLeft;var verticalScrollAmount =  ($window.pageYOffset || $document[0].documentElement.scrollTop) - currentScrollTop;element.css('transform', elementTransform);lastMouseEvent.pageX += horizontalScrollAmount;lastMouseEvent.pageY += verticalScrollAmount;$rootScope.$emit('draggable:_triggerHandlerMove', lastMouseEvent);}});};var clearInterval = function() {animationIsOn = false;};scope.$on('draggable:start', function(event, obj) {// Ignore this event if it's not for this element.if (obj.element[0] !== element[0]) return;if (!animationIsOn) createInterval();});scope.$on('draggable:end', function(event, obj) {// Ignore this event if it's not for this element.if (obj.element[0] !== element[0]) return;if (animationIsOn) clearInterval();});scope.$on('draggable:move', function(event, obj) {// Ignore this event if it's not for this element.if (obj.element[0] !== element[0]) return;lastMouseEvent = obj.event;});}};}]);

深究AngularJS——ng-drag、ng-drop相关推荐

  1. VMVare中Ubuntu报错:Drag and drop is not supported

    问题描述 VMVare中安装了VMVare tools的Ubuntu系统无法和win主机拖拽传输文件,并且报错:Drag and drop is not supported 解决方式 安装: sudo ...

  2. HTML5 仿QT 示例Drag and Drop Robot 换装机器人

    起源 在Qt的示例中看到了一个有趣的demo,截图如下: 这个demo的名字叫Drag and Drop Robot,简单概括而言,在这个demo中,可以把机器人四周的颜色拖动到机器人的各个部位,比如 ...

  3. Custom Client Side Drag and Drop Behavior in ASP.NET AJAX

    这是我的一篇在http://aspalliance.com/上的英文文章,限于版权协议中的排他性条款,这里只能给出一部分摘要引用.有兴趣的朋友可以到这里看到完整的全文:<Custom Clien ...

  4. html组态图动态拖拽,基于HTML5的Drag and Drop生成图片Base64信息

    HTML5的Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过Drag ...

  5. html5怎么设置drop,HTML5 拖放(Drag 和 Drop)

    拖放(Drag 和 drop)是 HTML5 标准的组成部分. 将 RUNOOB.COM 图标拖动到矩形框中. 拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标 ...

  6. iOS开发Drag and Drop简介

    1.Drag and Drop简介 Drag and Drop是iOS11的新特性,可以将文本.图片进行拖拽到不同app中,实现数据的传递.只不过只能在iPad上使用,iPhone上只能app内部拖拽 ...

  7. html拖放数据库字段,HTML5 拖放(Drag 和 Drop)

    拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. #div1 {width:350px;height:70px;padding:10p ...

  8. html item 左右滑动,拖动Html元素集合 Drag and Drop any item

    拖动Html元素集合 Drag and Drop any item 更新时间:2006年12月22日 00:00:00   作者: li { MARGIN-BOTTOM: 10px } ul { MA ...

  9. Android 用户界面---拖放(Drag and Drop)(二)

    拖拽事件监听器和回调方法 View对象既可以用实现View.OnDragListener接口的拖放事件监听器,也可以用View对象的onDragEvent(DragEvent)回调方法来接收拖拽事件. ...

最新文章

  1. 1137 - Sin your life sin公式 + 枚举
  2. 数据结构 - 简单选择排序法
  3. 又重装了系统win8+office2013+sql2012+tfs2012+vs2010+vs2012+xna4+kinectsdk1.6+wp8sdk
  4. C/C++ mysql 设置字符集
  5. c语言软件幻化,python字符串处理
  6. httpurlconnection 封装_不要再封装各种Util工具类了,看看这个框架
  7. 更改oracle背景,Oracle 11gR2修改用户后导致系统HANG住
  8. springboot+springcloud相关面试题
  9. Git命令集十四——抓取命令
  10. thread/threading——Python多线程入门笔记
  11. 网络管理员考试试题分类精解电子书
  12. 免费WebAR与小程序AR制作平台推荐
  13. 打算在县城“买”片地
  14. 实例61小写字母转大写
  15. 虚拟机VMware使用U盘装系统
  16. OpenCV + CPP 系列(卌二)图像特征匹配( KAZE/AKAZE)
  17. CSDN写博客——去水印or自定义水印#解密CSDN上传图片生成链接的内容
  18. Eclipse 报错 Cannot nest 'FisRptWeb/src/conf' inside library 'FisRptWeb/src'
  19. lyapunov指数求取时运用qr法与jacobi法之间的区别与联系【基于matlab的动力学模型学习笔记_10】
  20. 单片机原理与应用技术课后答案(3)

热门文章

  1. 验证异常处理调用顺序
  2. 从Github一开源项目ADSEC【学习域渗透攻防基础】
  3. win10下c/c++隐藏进程
  4. 1.9 实例:截取新闻标题
  5. 1.7 元注解作用及使用
  6. 用思科网络模拟器搭建一个简单的局域网
  7. c语言switch()语句
  8. Oracle的row_number函数
  9. undefind_undefined什么意思
  10. 20 个最常用的 Git 命令,码住!