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类库D
Oct 24 Javascript
关于javascript function对象那些迷惑分析
Oct 24 Javascript
javascript实现原生ajax的几种方法介绍
Sep 21 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
Feb 19 Javascript
jQuery统计上传文件大小的方法
Jan 24 Javascript
AngularJS中一般函数参数传递用法分析
Nov 22 Javascript
bootstrap table动态加载数据示例代码
Mar 25 Javascript
深入理解node.js之path模块
May 03 Javascript
bootstrap-table组合表头的实现方法
Sep 07 Javascript
JointJS JavaScript流程图绘制框架解析
Aug 15 Javascript
vue项目中使用bpmn为节点添加颜色的方法
Apr 30 Javascript
JavaScript 函数用法详解【函数定义、参数、绑定、作用域、闭包等】
May 12 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教程孙仲岳主讲
2008/01/07 PHP
php去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
使用PHP Socket 编程模拟Http post和get请求
2014/11/25 PHP
PHP单例模式详细介绍
2015/07/01 PHP
php实现的表单验证类完整示例
2019/08/13 PHP
TFDN图片播放器 不错自动播放
2006/10/03 Javascript
PJ Blog修改-禁止复制的代码和方法
2006/10/25 Javascript
Jquery Ajax的Get方式时需要注意URL地方
2011/04/07 Javascript
jquery win 7透明弹出层效果的简单代码
2013/08/06 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
JS判断form内所有表单是否为空的简单实例
2016/09/09 Javascript
使用JSON作为函数的参数的优缺点
2016/10/27 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
js实现截图保存图片功能的代码示例
2017/02/16 Javascript
ng2学习笔记之bootstrap中的component使用教程
2017/03/09 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
JavaScript实现的数字与字符串转换功能示例
2017/08/23 Javascript
react-native组件中NavigatorIOS和ListView结合使用的方法
2017/09/30 Javascript
react-native android状态栏的实现
2018/06/15 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
vue与原生app的对接交互的方法(混合开发)
2018/11/28 Javascript
详解js加减乘除精确计算
2019/03/19 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
python3.4用函数操作mysql5.7数据库
2017/06/23 Python
基于pycharm导入模块显示不存在的解决方法
2018/10/13 Python
基于Python+Appium实现京东双十一自动领金币功能
2019/10/31 Python
python3.7调试的实例方法
2020/07/21 Python
Python实现Canny及Hough算法代码实例解析
2020/08/06 Python
写给老师的表扬信
2014/01/21 职场文书
绘画专业自荐信范文
2014/02/23 职场文书
共产党员公开承诺书范文
2014/03/28 职场文书
消防工作实施方案
2014/06/09 职场文书
疾病证明书
2015/06/19 职场文书
详解MySQL事务的隔离级别与MVCC
2021/04/22 MySQL
Python基础 括号()[]{}的详解
2021/11/07 Python