深究AngularJS中ng-drag、ng-drop的用法


Posted in Javascript onJune 12, 2017

1.相关地址:

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

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方法的参数说明:

  1. $index : 表示拖动的数据所落的元素的下标
  2. $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 handler
        var _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 tagnames
          if (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 events
          if (_dragHandle) {
            // handle(s) specified, use those to initiate drag
            _dragHandle.on(_pressEvents, onpress);
          } else {
            // no handle(s) specified, use the element as the handle
            element.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-click
            return;
          }

          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':''});
          else
            element.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 listeners

          if (!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 return
          if (!_dropEnabled || _myid === obj.uid) {
            updateDragStyles(false, obj.element);
            return;
          }
          if (isTouching(obj.x, obj.y, obj.element)) {
            // call the ngDraggable ngDragSuccess element callback
            if(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 listeners

          if (!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 listeners

          if (!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;
        });
      }
    };
  }]);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript小技巧 2.5 则
Sep 12 Javascript
基于jquery实现点击左右按钮图片横向滚动
Apr 11 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
May 17 Javascript
JavaScript动态操作表格实例(添加,删除行,列及单元格)
Nov 25 Javascript
jquery ajaxSubmit 异步提交的简单实现
Feb 28 Javascript
javascript记录文本框内文字个数检测文字个数变化
Oct 14 Javascript
bootstrap table复杂操作代码
Nov 01 Javascript
JS实现带动画的回到顶部效果
Dec 28 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
Mar 04 Javascript
实现高性能javascript的注意事项
May 27 Javascript
微信小程序如何使用globalData的方法
Jun 06 Javascript
如何基于JS截获动态代码
Dec 25 Javascript
深究AngularJS中$sce的使用
Jun 12 #Javascript
JS身份证信息验证正则表达式
Jun 12 #Javascript
用原生JS实现简单的多选框功能
Jun 12 #Javascript
Angularjs 双向绑定时字符串的转换成数字类型的问题
Jun 12 #Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
Jun 12 #Javascript
AngularJS 异步解决实现方法
Jun 12 #Javascript
jquery+css实现侧边导航栏效果
Jun 12 #jQuery
You might like
php巧获服务器端信息
2006/12/06 PHP
php简单静态页生成过程
2008/03/27 PHP
php jquery 多文件上传简单实例
2013/12/23 PHP
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
php 三大特点:封装,继承,多态
2017/02/19 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
PHP实现文件上传与下载
2020/08/28 PHP
JavaScript的parseInt 取整使用
2011/05/09 Javascript
jquery获取table中的某行全部td的内容方法
2013/03/08 Javascript
Jquery 自定义动画概述及示例
2013/03/29 Javascript
简单选项卡 js和jquery制作方法分享
2014/02/26 Javascript
AngularJS入门教程之路由与多视图详解
2016/08/19 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
js实现类bootstrap模态框动画
2017/02/07 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
jQuery、layer实现弹出层的打开、关闭功能
2017/06/28 jQuery
backbone简介_动力节点Java学院整理
2017/07/14 Javascript
JavaScript生成指定范围随机数和随机序列的方法
2018/05/05 Javascript
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
Python入门教程之运算符与控制流
2016/08/17 Python
PyTorch上搭建简单神经网络实现回归和分类的示例
2018/04/28 Python
浅谈TensorFlow中读取图像数据的三种方式
2020/06/30 Python
Python调用ffmpeg开源视频处理库,批量处理视频
2020/11/16 Python
html5中canvas学习笔记2-判断浏览器是否支持canvas
2013/01/06 HTML / CSS
浅谈HTML5 FileReader分布读取文件以及其方法简介
2017/11/09 HTML / CSS
移动端html5模拟长按事件的实现方法
2018/09/30 HTML / CSS
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
中国包裹转运寄送国际服务:Famiboat
2019/07/24 全球购物
UNIX命令速查表
2012/03/10 面试题
认识深刻的检讨书
2014/02/16 职场文书
升学宴来宾致辞
2015/07/27 职场文书
《家》读后感:万惜拯救,冷暖自知
2019/09/25 职场文书
Python图片检索之以图搜图
2021/05/31 Python
Python使用PyYAML库读写yaml文件的方法
2022/04/06 Python
Python中的socket网络模块介绍
2022/07/23 Python