AngularJS自定义指令详解(有分页插件代码)


Posted in Javascript onJune 12, 2017

前言

除了 AngularJS 内置的指令外,我们还可以创建自定义指令。

通过 .directive() 函数来添加自定义的指令。

调用自定义指令时,需要在HTMl 元素上添加自定义指令名。

自定义指令命名规则:使用驼峰命名法来命名,即除第一个单词外的首字母需大写。如: myDirective。

在html页面调用该指令时需要以 - 分割,如: my-directive。示例代码:

<body ng-app="myApp">

<my-directive></my-directive>

<script>
 var app = angular.module("myApp", []);
 app.directive("myDirective", function() {
  return {
   template : "<h1>模板:可以写自己的html页面代码</h1>"
  };
 });
</script>

</body>

html页面调用自定义指令的四种方式

通过在自定义指令里添加 restrict 属性,根据设置不同的值来决定html页面的调用方式,如:

var app = angular.module("myApp", []);
app.directive("myDirective", function() {
 return {
  restrict : "A",//只能通过属性调用
  template : "<h1>自定义指令!</h1>"
 };
});

restrict值的不同,决定了调用方式的不同

属性值 调用方式 示例
A (Attribute首字母) 属性名
C (Class 首字母) 类名
E (Element 首字母) 元素名
M 注释

restrict 默认值为 EA, 即在html页面可通过元素名和属性名来调用自定义指令。

自定义指令属性详解

属性 值类型 说明
restrict string 指令的调用方式,A、C、E、M
priority number 指令执行的优先级
template string 指令使用的模板,可将html页面代码写于此。只能与templateUrl二选其一
templateUrl string 从指定的url地址加载模板。只能与template二选其一
replace boolean 是否用模板替换当前元素。true : 将指令标签替换成temple中定义的内容,页面上不会再有标签;false :则append(追加)在当前元素上,即模板的内容包在标签内部。默认false。
transclude boolean 是否将当前元素的内容转移到模板中
scope boolean /object 指定指令的作用域。false(默认值): 使用父作用域作为自己的作用域(每个引用自定义指令的标签若其中一个标签改变某一变量值,则会影响其他标签的值 )。true: 新建一个作用域,该作用域继承父作用域(两个引用自定义指令的标签之间的变量互不影响)。JavaScript对象:与父作用域隔离,并指定可以从父作用域访问的变量
controller function 定义与其他指令进行交互的接口函数
require string 指定需要依赖的其他指令
link function 以编程的方式操作DOM,包括添加监听器等
compile function 编程的方式修改DOM模板的副本,可以返回链接函数

对表格里的知识进行延伸

1.templateUrl

如果template里拼写的html页面代码十分的多页复杂,拼字符串的话就太麻烦啦,这里我们就可以选择templateUrl。我们可以将要拼写的html页面代码独立到一个页面里,如template.html;然后再指定该html文件所在的路径即可,如templateUrl:”template.html”。用到该自定义指令时,会自动发一个http请求来获取template.html对应的模板内容。这样做的缺点是,多了一个http请求。别急,可以改进的:

angularjs规定了模板还可以用<Script>标签定义:

<script type="text/ng-template" id="template.html">
   <div>自定义指令模板用Script标签定义的方式,须放在html页面ng-controller指令所在标签的内部</div>
</script>

上面代码写在html页面的ng-controller指令所在标签的里面,这样就不用再去请求它了。示例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> 
</head>
<body >
 <div ng-app="myApp" ng-controller="myController">

  <!-- 引用自定义指令 -->
  <my-directive></my-directive>

  <!-- 模板代码:须放在myController所在标签内部 -->
  <script type="text/ng-template" id="template.html">
   <div> 自定义指令模板的templateUrl形式</div>
  </script>
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope) { });
  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    restrict:'E',
    templateUrl : "template.html"
   };
  });
 </script>
</body>

</html>

有多个模板时,我们可以将所有的模板集中在一个文件中,只需加载一次,然后根据id的不同调用不同的模板。

2.transclude

定义是否将当前元素(html页面的自定义指令)的内容转移到模板中。
模板中要接收当前元素内容的标签需要使用ng-transclude指令。

<body >
 <div ng-app="myApp" ng-controller="myController">
  <!-- 引用自定义指令 -->
  <my-directive>自定义指定令内容</my-directive>

  <!-- 模板代码 -->
  <script type="text/ng-template" id="template.html">
   <div> 模板内容</div>
   <div ng-transclude></div>//模板接收上面自定义指令间的内容
  </script>
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope) { });
  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    templateUrl : "template.html",
     transclude : true//转移到模板中
   };
  });
 </script>
</body>

3.什么是scope的父作用域

引用自定义指令的html页面的控制器所能控制的范围。下面代码的父作用域就是myController所控制的范围

<body >
 <div ng-app="myApp" ng-controller="myController">  
  <my-directive></my-directive><!-- 引用自定义指令 -->
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope){ });
  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    template : "<h1>自定义指令!</h1>"
   };
  });
 </script>
</body>

4.scope属性的值是对象(object)时的用法

AngularJS内置指令的用法:ng-model=”obj”,通过obj这个变量双向绑定值,controller里变了,html页面也跟着变化。这说明,内置指令不仅可作为属性,还可动态改变值,这个要是不懂的,看看基础语法。如下代码:

<div ng-app="myApp" ng-controller="myController">
 要动态变化的内容: <input ng-model="obj">
</div>

<script>
 var app = angular.module('myApp', []);
 app.controller('myController', function($scope) {
  $scope.obj = "这个字符串值会同步到html里";
 });
</script>

自定义指令当然也需要实现这种功能啦。scope属性为对象时,可为自定义指令指定一个可以绑定值的属性。这里还得说明一下的是,这个scope属性与自定义指令里link属性里的scope参数是一个变量。

<!-- =符号的用法-->
<body >
 <div ng-app="myApp" ng-controller="myController">
  <!-- 引用自定义指令:obj变量与控制器里的objc变量双向绑定了值 -->
  <my-directive speak="obj"></my-directive>
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);

  //创建控制器
  app.controller('myController', function($scope) { 
   $scope.obj="父作用域";//父作用域给自定义指令属性赋的值
  });

  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    template : "<p>模板内容</p>",
    scope:{
     title:"=speak"//定义一个speak属性供html页面的自定义指令用。如果写成title:"="格式,则自定义指令里的属性名就是title。
    },
    link: function postLink(scope, iElement, iAttrs) {
     console.log(scope.title)//这里打印的值与控制器里的值一样
    }
   };
  });
 </script>
</body>

有了前面的一个示例,下面再来说说绑定策略:即用符号前缀给自定义指令传值。它是一个键值对,键是在自定义指令中使用的,值里符号后面的字符串是html页面自定义指令的属性名;如果值里只有符号,则html页面自定义指令的属性名就是键名。

符号 说明 示例
@ 值传递,单向绑定。html页面自定义指令里的val属性的值可传给link的scope使用。第一种写法——str : “@”,这种写法html页面的指令属性名为str str : “@val”,属性名为val
= 双向绑定数据到指令的属性中,数据值可以是任意类型的。第一种写法:name : “=”,这种写法html页面的自定义指令属性名就是name name : “=username”,属性名是username
& 使用父作用域中的一个函数,可以在指令中调用。第一种写法:getName:”&”,这种写法html页面的自定义指令属性名就是gegName getName : “&getUserName”,属性名是getUserName

其余两种符号用法:

<!-- @符号的用法 -->
<body >
 <div ng-app="myApp" ng-controller="myController">
  <!-- 引用自定义指令 -->
  <my-directive title="obj" str="abcd">自定义指定令的内容555</my-directive>
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope) { 
   $scope.obj="父作用域";//父作用域给自定义指令属性赋的值
  });
  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    template : "<p >模板内容</p>",
    scope:{
     title:"=",
     str:"@"
    },
    link: function postLink(scope, iElement, iAttrs) {
     console.log(scope.str)
     console.log(scope.title)
    }
   };
  });
 </script>
</body>
<!-- &符号的用法 -->
<body >
 <div ng-app="myApp" ng-controller="myController">
  <!-- 引用自定义指令 -->
  <my-directive fun="test()"></my-directive>
 </div>

 <script>
  //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope) { 
   $scope.test = function(){
     console.log('自定义指令会调用该法,所以这句话会打印到控制台上')
   }
  });
  //创建自定义指令
  app.directive("myDirective", function() {
   return {
    template : "<p >模板内容</p>",
    scope:{
     fun:"&"//属性名直接是fun
    },
    link: function postLink(scope, iElement, iAttrs) {
     scope.fun();//调用父作用域的方法,好似不能传参,未深究。
    }
   };
  });
 </script>
</body>

5.controller属性

controller属性用于提供对外的接口,即该自定义指令会被其他自定义指令调用。所谓的接口,就是this后的变量或方法。

controller可以使用的参数,作用域、节点、节点的属性、节点内容的迁移,这些都可以通过依赖注入被传进来,所以你可以根据需要只写要用的参数,有$scope,Z$element, $attrs, $transclude。

调用该自定义指令的指令需要放在该指令之间。假定firstDirective指令是要被调用的自定义指令,expander是调用者指令。如下:

<first-directive>
  <expander ng-repeat="item in list" attribute="list">{{item.title}}:{{item.text}}</expander>
 </first-directive>

既然firstDirective内部还有指令,则firstDirective必须配置transclude属性为true。代码如下:

//用于被调用的自定义指令
 app.directive('firstDirective',function(){
  return {
   template : '<div ng-transclude></div>',
   replace : true,
   transclude : true,
   controller :function(){
    this.getData = function(val){
      var data = 3 * val;
     return data;
    }
    this.a = "abc";
   }
  }
 });

调用其他指令的自定义指令必须配置require属性指定指令名。然后在link函数里就可注入要调用的指令。

//自定义指令
 app.directive('expander',function(){
  return {
   templateUrl : 'template.html',
   replace : true,
   transclude : true,
   require : '^?firstDirective',//引用其他自定义指令,^表示从父节点开始找,?表示将告诉$compile服务,如果所需的指令没找到,不要抛出异常
   scope : {
    title : '=attribute'
   },
   link : function(scope,element,attris,firstDirct){//注入
    console.log(firstDirct.a)//调用其他指令的变量
    console.log(firstDirct.getData(6)) //调用其他指令的方法    
   }
  };
 });

6.link属性用法

link后的方法在指令中负责执行DOM 操作和注册事件监听器等。link函数有五个参数(scope,element,attrs,controller,linker)。link 方法的参数解释:

scope: 它与自定义指令里的scope属性是一个东西。它是指令scope的引用,所以可改名为sco等其他名字。scope 变量在初始化时是不被定义的,link 方法会注册监视器监视值变化事件。

element: 包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jquery,还可以使用Angular's jqLite )。

controller: 在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互,如前面的例子。

注意:当调用link 方法时, 通过值传递(”@”)的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。

7.link与compile的区别

compile函数有三个参数(cElement,cAttrs,cLinker),使用compile函数可以在ng创建原始dom实例以及创建scope实例之前,改变原始的dom(template element);可以应用于当需要生成多个element实例但只有一个template element的情况,ng-repeat就是一个最好的例子。它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后每个又生成element实例。因为compile只会运行一次,所以当你需要生成多个element实例的时候是可以提高性能的。

link函数有五个参数(scope,element,attrs,ctrl,linker)。

link又分为pre-link和post-link,在代码里直接用pre和post表示,当我们直接使用link时,默认跟post一样。我在网上找了个例子来说明一下区别,代码如下:

<body>
 <div ng-app="myApp" ng-controller="myController">
  <level-one>
   <level-two>
    <level-three> Hello </level-three>
   </level-two>
  </level-one>
 </div>
 <script>
   //创建模块
  var app = angular.module('myApp', []);
  //创建控制器
  app.controller('myController', function($scope) { 

  });
  //自定义指令
  function createDirective(name){
   return function(){
   return {
    restrict: 'E',
    compile: function(tElem, tAttrs){
    console.log(name + ': compile => ' + tElem.html());
    return {
     pre: function(scope, iElem, iAttrs){
     console.log(name + ': pre link => ' + iElem.html());
     },
     post: function(scope, iElem, iAttrs){
     console.log(name + ': post link => ' + iElem.html());
     }
    }
    }
   }
   }
  }

  app.directive('levelOne', createDirective('levelOne'));
  app.directive('levelTwo', createDirective('levelTwo'));
  app.directive('levelThree', createDirective('levelThree'));
 </script>
</body>

注意打印结果:

levelOne: compile => 
  <level-two>
   <level-three>
    Hello 
   </level-three>
  </level-two>
 levelTwo: compile => 
   <level-three>
    Hello 
   </level-three>
 levelThree: compile => 
    Hello 
 levelOne: pre link => 
  <level-two>
   <level-three>
    Hello 
   </level-three>
  </level-two>

levelTwo: pre link => 
   <level-three>
    Hello 
   </level-three>

levelThree: pre link => 
    Hello 

levelThree: post link => 
    Hello 
levelTwo: post link => 
   <level-three>
    Hello 
   </level-three>

levelOne: post link => 
  <level-two>
   <level-three>
    Hello 
   </level-three>
  </level-two>

分析打印结果:

运行levelone指令中的compile函数,ng就会递归遍历它的dom节点,然后在level-two与level-three上面重复这些操作。所以会依次打印连续三个compile。

pre会在所有compile执行完后且在所有post之前执行。这样可以在执行post前执行一些其他代码,有些类似AOP。

由上面结果可知,post的执行顺序却是先levelthree最后levelone,即反向调用相关联的post-link函数。这么做的好处是,当我们运行levelone时,保证leveltwo与levelthree都已经执行过了,这样就会更安全。所以默认的link就是post。

一个我做过的分页例子

之所以展示这个代码,主要是给一些朋友看看真实的项目,,多余的东西删掉了,具体的注入这里就不在讲了。

html页面代码:

<div class="wp-20" ng-controller="AppStatisticController" ng-cloak>
 <div class="panel-footer">
  <s-pagination conf="paginationConf"></s-pagination>
 </div>
</div>

控制器代码:

"use strict";//严格

define(["application-configuration", "s-pagination", "tableDataService"], function (app) {
 app.register.controller("AppStatisticController", ["$scope", "$rootScope", "$stateParams","$http", "tableDataService",
  function($scope, $rootScope, $stateParams, $http, tableDataService) {  

   var getTableDataSuccess = function(result) {
    if(result.c == 1) {
     $scope.title = result.title;
     $scope.lists = result.pageList;
     $scope.total = result.data;
     $scope.paginationConf.totalItems = result.total;
    }else if(result.c == 2){
     //弹出框,没有查到数据 
    } else {
     alert(result.i);
    }
   };

   var getTableDataError = function(result) {
    alert(result);
   };
   /*重要的代码,这个paginationConf与自定义指令双向绑定数据*/
   $scope.paginationConf = {
    currentPage: 1,
    itemsPerPage: 10,
    pagesLength: 9,
    search: false,
    onChange: function() {
     var param = {
      "pageNo": this.currentPage,
      "pageSize": this.itemsPerPage,
      "timeType": $scope.formData.timeType,
      "adStyle":$scope.formData.adStyle,
     };
     param.appId = $stateParams.appId;
     tableDataService.getTableData(
      param,
      "ims/appStat.do",
      getTableDataSuccess,
      getTableDataError
     );
    }
   };

   $scope.$watch("formData",function(newValue,oldValue, scope) {
    if(newValue.keywords == oldValue.keywords) {
      $scope.paginationConf.search = true;
    }
   }, true);

  }]);
});

自定义指令代码:也算是angularJS的分页插件

/**
 * 分页插件封装s-pagination.js
 * @date 2016-05-06
 * @author Peter
 */

angular.module('s.pagination', []).directive('sPagination',[function(){//自定义指令
 return {
  restrict: 'E',//仅限元素名调用
  template: '<div class="page-list">' +
  '<ul class="pagination" ng-show="conf.totalItems > 0">' +
  '<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()"><span>«</span></li>' +
  '<li ng-repeat="item in pageList track by $index" ng-class="{active: item == conf.currentPage, separate: item == \'...\'}" ' +
  'ng-click="changeCurrentPage(item)">' +
  '<span>{{ item }}</span>' +
  '</li>' +
  '<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()"><span>»</span></li>' +
  '</ul>' +
  '<div class="page-total" ng-show="conf.totalItems > 0">' +
  '第<input type="text" ng-model="jumpPageNum" ng-keyup="jumpToPage($event)"/>页 ' +
  '每页<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions "></select>' +
  '/共<strong>{{ conf.totalItems }}</strong>条' +
  '</div>' +
  '<div class="no-items" ng-show="conf.totalItems <= 0">暂无数据</div>' +
  '</div>',
  replace: true,
  scope: {
   conf: '='//双向绑定数据
  },
  link: function(scope, element, attrs){
   // 变更当前页
   scope.changeCurrentPage = function(item) {
    if(item == '...'){
     return;
    }else{
     scope.conf.currentPage = item;
    }
   };

   // 定义分页的长度必须为奇数 (default:5)
   scope.conf.pagesLength = parseInt(scope.conf.pagesLength) ? parseInt(scope.conf.pagesLength) : 5 ;
   if(scope.conf.pagesLength % 2 === 0){
    // 如果不是奇数的时候处理一下
    scope.conf.pagesLength = scope.conf.pagesLength -1;
   }

   // conf.erPageOptions
   if(!scope.conf.perPageOptions){
    scope.conf.perPageOptions = [10, 20, 30, 40, 50];
   }

   // pageList数组
   function getPagination(newValue, oldValue) {
    //新增属性search 用于附加搜索条件改变时触发
    if(newValue[1] != oldValue[1] || newValue[2] != oldValue[2]) {
     scope.conf.search = true;
    }
    // conf.currentPage
    scope.conf.currentPage = parseInt(scope.conf.currentPage) ? parseInt(scope.conf.currentPage) : 1;

    // conf.totalItems
    scope.conf.totalItems = parseInt(scope.conf.totalItems) ? parseInt(scope.conf.totalItems) : 0;

    // conf.itemsPerPage (default:15)
    scope.conf.itemsPerPage = parseInt(scope.conf.itemsPerPage) ? parseInt(scope.conf.itemsPerPage) : 15;

    // numberOfPages
    scope.conf.numberOfPages = Math.ceil(scope.conf.totalItems/scope.conf.itemsPerPage);

    // judge currentPage > scope.numberOfPages
    if(scope.conf.currentPage < 1){
     scope.conf.currentPage = 1;
    }

    // 如果分页总数>0,并且当前页大于分页总数
    if(scope.conf.numberOfPages > 0 && scope.conf.currentPage > scope.conf.numberOfPages){
     scope.conf.currentPage = scope.conf.numberOfPages;
    }

    // jumpPageNum
    scope.jumpPageNum = scope.conf.currentPage;

    // 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
    var perPageOptionsLength = scope.conf.perPageOptions.length;
    // 定义状态
    var perPageOptionsStatus;
    for(var i = 0; i < perPageOptionsLength; i++){
     if(scope.conf.perPageOptions[i] == scope.conf.itemsPerPage){
      perPageOptionsStatus = true;
     }
    }
    // 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
    if(!perPageOptionsStatus){
     scope.conf.perPageOptions.push(scope.conf.itemsPerPage);
    }

    // 对选项进行sort
    scope.conf.perPageOptions.sort(function(a, b){return a-b});

    scope.pageList = [];
    if(scope.conf.numberOfPages <= scope.conf.pagesLength){
     // 判断总页数如果小于等于分页的长度,若小于则直接显示
     for(i =1; i <= scope.conf.numberOfPages; i++){
      scope.pageList.push(i);
     }
    }else{
     // 总页数大于分页长度(此时分为三种情况:1.左边没有...2.右边没有...3.左右都有...)
     // 计算中心偏移量
     var offset = (scope.conf.pagesLength - 1)/2;
     if(scope.conf.currentPage <= offset){
      // 左边没有...
      for(i =1; i <= offset +1; i++){
       scope.pageList.push(i);
      }
      scope.pageList.push('...');
      scope.pageList.push(scope.conf.numberOfPages);
     }else if(scope.conf.currentPage > scope.conf.numberOfPages - offset){
      scope.pageList.push(1);
      scope.pageList.push('...');
      for(i = offset + 1; i >= 1; i--){
       scope.pageList.push(scope.conf.numberOfPages - i);
      }
      scope.pageList.push(scope.conf.numberOfPages);
     }else{
      // 最后一种情况,两边都有...
      scope.pageList.push(1);
      scope.pageList.push('...');

      for(i = Math.ceil(offset/2) ; i >= 1; i--){
       scope.pageList.push(scope.conf.currentPage - i);
      }
      scope.pageList.push(scope.conf.currentPage);
      for(i = 1; i <= offset/2; i++){
       scope.pageList.push(scope.conf.currentPage + i);
      }

      scope.pageList.push('...');
      scope.pageList.push(scope.conf.numberOfPages);
     }
    }

    if(scope.conf.onChange){
     //请求数据
     if(scope.conf.search) {
      scope.conf.onChange();
      scope.conf.search = false;
     }

    }
    scope.$parent.conf = scope.conf;
   }

   // prevPage
   scope.prevPage = function(){
    if(scope.conf.currentPage > 1){
     scope.conf.currentPage -= 1;
    }
   };
   // nextPage
   scope.nextPage = function(){
    if(scope.conf.currentPage < scope.conf.numberOfPages){
     scope.conf.currentPage += 1;
    }
   };

   // 跳转页
   scope.jumpToPage = function(){
    scope.jumpPageNum = scope.jumpPageNum.replace(/[^0-9]/g,'');
    if(scope.jumpPageNum !== ''){
     scope.conf.currentPage = scope.jumpPageNum;
    }
   };

   scope.$watch(function() {

    if(!scope.conf.totalItems) {
     scope.conf.totalItems = 0;
    }
    if(angular.isUndefined(scope.conf.search)) {
     scope.conf.search = false;
    }

    var newValue = [scope.conf.totalItems, scope.conf.currentPage, scope.conf.itemsPerPage, scope.conf.search];
    return newValue;
   }, getPagination, true);
  }
 };
}]);

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

Javascript 相关文章推荐
学习并汇集javascript匿名函数
Nov 25 Javascript
jQuery创建插件的代码分析
Apr 14 Javascript
在JS数组特定索引处指定位置插入元素的技巧
Aug 24 Javascript
JavaScript语言对Unicode字符集的支持详解
Dec 30 Javascript
轻量级网页遮罩层jQuery插件用法实例
Jul 31 Javascript
简单实现Vue的observer和watcher
Dec 21 Javascript
基于Vue.js 2.0实现百度搜索框效果
Dec 28 Javascript
Three.js实现浏览器变动时进行自适应的方法
Sep 26 Javascript
说说如何利用 Node.js 代理解决跨域问题
Apr 22 Javascript
深入理解 TypeScript Reflect Metadata
Dec 12 Javascript
mpvue 项目初始化及实现授权登录的实现方法
Jul 20 Javascript
js实现上传图片到服务器
Apr 11 Javascript
前端构建工具之gulp的语法教程
Jun 12 #Javascript
前端构建工具之gulp的配置与搭建详解
Jun 12 #Javascript
微信小程序 自定义Toast实例代码
Jun 12 #Javascript
Angular4 中常用的指令入门总结
Jun 12 #Javascript
Node.js 8 中的 util.promisify的详解
Jun 12 #Javascript
jquery处理checkbox(复选框)是否被选中实例代码
Jun 12 #jQuery
实现微信小程序的wxml文件和wxss文件在webstrom的支持
Jun 12 #Javascript
You might like
ADODB的数据库封包程序库
2006/12/31 PHP
ECSHOP完美解决Deprecated: preg_replace()报错的问题
2016/05/17 PHP
PHP PDOStatement::fetchColumn讲解
2019/01/31 PHP
laravel框架查询数据集转为数组的两种方法
2019/10/10 PHP
使用JavaScript检测Firefox浏览器是否启用了Firebug的代码
2010/12/28 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
jquery的map与get方法详解
2013/11/04 Javascript
用javascript为页面添加天气显示实现思路及代码
2013/12/02 Javascript
javascript设置连续两次点击按钮时间间隔的方法
2014/10/28 Javascript
js获取form的方法
2015/05/06 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
JavaScript学习笔记整理_setTimeout的应用
2016/09/19 Javascript
使用JavaScript触发过渡效果的方法
2017/01/19 Javascript
js实现自定义路由
2017/02/04 Javascript
JS字符串false转boolean的方法(推荐)
2017/03/08 Javascript
深入解析Vue 组件命名那些事
2017/07/18 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
2018/12/29 jQuery
使用mixins实现elementUI表单全局验证的解决方法
2019/04/02 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
vue 检测用户上传图片宽高的方法
2020/02/06 Javascript
vue中的.$mount('#app')手动挂载操作
2020/09/02 Javascript
Python实现Youku视频批量下载功能
2017/03/14 Python
详解Django rest_framework实现RESTful API
2018/05/24 Python
使用Python Pandas处理亿级数据的方法
2019/06/24 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
Pyinstaller加密打包应用的示例代码
2020/06/11 Python
浅谈优化Django ORM中的性能问题
2020/07/09 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
HTML中使用SVG与SVG预定义形状元素介绍
2013/06/28 HTML / CSS
Foot Locker澳洲官网:美国运动服和鞋类零售商
2019/10/11 全球购物
营销专业应届生求职信
2013/11/26 职场文书
父母对孩子说的话
2014/04/12 职场文书
刑事代理授权委托书
2014/09/17 职场文书
欧也妮葛朗台读书笔记
2015/06/30 职场文书
人事行政部各岗位职责说明书!
2019/07/15 职场文书
导游词之天下银坑景区
2019/11/21 职场文书