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 相关文章推荐
利用js跨页面保存变量做菜单的方法
Jan 17 Javascript
Mootools 1.2教程 定时器和哈希简介
Sep 15 Javascript
javascript textarea光标定位方法(兼容IE和FF)
Mar 12 Javascript
页面装载js及性能分析方法介绍
Mar 21 Javascript
javascript html5移动端轻松实现文件上传
Mar 27 Javascript
JS+CSS3模拟溢出滚动效果
Aug 12 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
Oct 13 Javascript
jQuery中值得注意的trigger方法浅析
Dec 12 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
Mar 14 Javascript
快速掌握jquery分页插件jqPaginator的使用方法
Aug 09 jQuery
JavaScript中Array方法你该知道的正确打开方法
Sep 11 Javascript
详解Vue.js中引入图片路径的几种方式
Jun 17 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
分享一个PHP数据流应用的简单例子
2012/06/01 PHP
php使用curl检测网页是否被百度收录的示例分享
2014/01/31 PHP
php操作mysql数据库的基本类代码
2014/02/25 PHP
Laravel 之url参数,获取路由参数的例子
2019/10/21 PHP
探索Emberjs制作一个简单的Todo应用
2012/11/07 Javascript
js转义字符介绍
2013/11/05 Javascript
jQuery中is()方法用法实例
2015/01/06 Javascript
JQuery Mobile实现导航栏和页脚
2016/03/09 Javascript
JavaScript之WebSocket技术详解
2016/11/18 Javascript
JS实现微信弹出搜索框 多条件查询功能
2016/12/13 Javascript
layerUI下的绑定事件实例代码
2018/08/17 Javascript
js实现延迟加载的几种方法详解
2019/01/19 Javascript
jQuery事件多次绑定与解绑问题实例分析
2019/02/19 jQuery
redux.js详解及基本使用
2019/05/24 Javascript
小程序实现横向滑动日历效果
2019/10/21 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
2020/05/23 Javascript
利用PHP实现递归删除链表元素的方法示例
2020/10/23 Javascript
跟老齐学Python之集合的关系
2014/09/24 Python
在ironpython中利用装饰器执行SQL操作的例子
2015/05/02 Python
基于Python实现文件大小输出
2016/01/11 Python
Python实现TCP/IP协议下的端口转发及重定向示例
2016/06/14 Python
python elasticsearch从创建索引到写入数据的全过程
2019/08/04 Python
python 解决pycharm运行py文件只有unittest选项的问题
2020/09/01 Python
如何创建一个Flask项目并进行简单配置
2020/11/18 Python
python爬虫今日热榜数据到txt文件的源码
2021/02/23 Python
一款html5 canvas实现的图片玻璃碎片特效
2014/09/11 HTML / CSS
澳大利亚新奇小玩意网站:Yellow Octopus
2017/12/28 全球购物
来自世界各地的优质葡萄酒:VineShop24
2018/07/09 全球购物
西班牙品牌鞋子、服装和配饰在线商店:Esdemarca
2021/02/17 全球购物
师范生实习个人的自我评价
2013/09/28 职场文书
合作意向协议书范本
2014/03/31 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
工商管理本科生求职信
2014/07/13 职场文书
纪委书记群众路线整改措施思想汇报
2014/10/09 职场文书
婚前协议书范本两则
2014/10/16 职场文书
租赁协议书
2015/01/27 职场文书