angularjs短信验证码及秒倒计时

阅读更多

  工作H5开发需要做短信验证码及秒倒计时,如果是用纯JS做好像还比较容易,但用angularJS做还是一些坑,特此记录一下,有如下几种实现方式。

一.setTimeout方式实现



	AngularJs倒计时


	

index.js

var app = angular.module('myModule', []);

app.controller('registerCtrl', function($scope,$interval){
   	let countDown = 10;
	$scope.timing = countDown + "s";
	
	$scope.verifCode = '';
	$scope.verifCodeDisabled = false;
	$scope.submitBtnDisabled = false;
	
	function settime() {
		if(countDown > 0) {
			setTimeout(function() {settime(countDown--); $scope.$apply();}, 1000);
			$scope.timing = countDown + 's';
		}else {
			$scope.timing = "重新获取";
			$scope.verifCodeDisabled = true;
			$scope.submitBtnDisabled = true;
		}
	}
	
	settime();
	
	$scope.reacQuire = function() {
		if(countDown <= 0) {
			countDown = 10;
			$scope.timing = countDown + "s";
			settime();
            $scope.verifCodeDisabled = false;
			$scope.submitBtnDisabled = false;
		}
	};
	
	$scope.submitBtn = function() {
		if(!$scope.verifCode) {
			alert('请输入验证码');
			return;
		}
		alert('提交成功');
	};
});

angular.element(document).ready(function() {   
	angular.bootstrap(document,['myModule']);  
});

运行效果:


  当倒计到0,输入框和“提交”按钮变灰,倒计时按钮变成“重新获取”,如下所示:


  在这里的实现在,必须注意settime函数中的$scope.$apply();在这里,如果没有$scope.$apply();则倒计时,只会倒计一次,虽然JS确实在一秒一秒的减少,但由于异步(延迟)的存在,当开始执行回调函数的时候,angularJS自身controller中的脏值检测已经结束,无法检测到回调函数导致数据的变化,导致页面无法正常倒计时间。同样,如果在settime函数级别加上$scope.$apply();效果确实可以,但F12可以看到angularJS报错$apply already in progress。详见:理解和解决angularJS报错$apply already in progress。

 

二.修改网上查看的实现方式,也能达到目的



	AngularJs倒计时


	
	
	
	

app.js

var app = angular.module('myModule', []);

app.controller('registerCtrl', function($scope, $interval) {
	
    $scope.paracont = "获取验证码";  
    $scope.paraclass = "but_null";  
    $scope.paraevent = true;
   
    var second = 10, timePromise = undefined;  
   
    function interval(){  
	  if(second<=0){  
		$interval.cancel(timePromise);  
		timePromise = undefined;  
		
		$scope.paracont = "重发验证码";  
		$scope.paraclass = "but_null";  
		$scope.paraevent = true;  
	  }else{  
		$scope.paracont = second + "秒后可重发";  
		$scope.paraclass = "not but_null";  
		second--;
	  }  
    }
	
	timePromise = $interval(interval, 1000, 100); //表示每一秒执行一次,执行100次
    
	$scope.sendphonecode = function() {
		if(second <= 0) {
			second = 10;
			timePromise = $interval(interval, 1000, 100); //表示每一秒执行一次,执行100次
		}
	};
});

angular.element(document).ready(function() {   
	angular.bootstrap(document,['myModule']);  
});

运行效果:

 

三.用$interval实现



	AngularJs倒计时


	

index02.js

var app = angular.module('myModule', []);

app.controller('registerCtrl', function($scope,$interval){
   	let countDown = 10;
	$scope.timing = countDown + "s";
	
	$scope.verifCode = '';
	$scope.verifCodeDisabled = false;
	$scope.submitBtnDisabled = false;
	
	var time = $interval(interval, 1000);
	
	function interval() {
		countDown--;
		$scope.timing = countDown + "s";
		if(countDown <= 0) {
			$interval.cancel(time);
			$scope.timing = "重新获取";
			$scope.verifCodeDisabled = true;
			$scope.submitBtnDisabled = true;
		}
	}
	
	$scope.reacQuire = function() {
		if(countDown <= 0) {
			countDown = 10;
			$scope.timing = countDown + "s";
			time = $interval(interval, 1000);
			$scope.verifCodeDisabled = false;
			$scope.submitBtnDisabled = false;
		}
	};
	
	$scope.submitBtn = function() {
		if(!$scope.verifCode) {
			alert('请输入验证码');
			return;
		}
		alert('提交成功');
	};
});

angular.element(document).ready(function() {   
	angular.bootstrap(document,['myModule']);  
});

运行效果同方法一。

 

四.指令方式



	AngularJs倒计时


	
获取验证码

index03.js

var app = angular.module('myModule', []);

app.controller('registerCtrl', function($scope, $interval){
   	$scope.initTime = false;
	$scope.timeoutValue = 10000;
});

app.directive('timerButton', function($timeout, $interval){
    return {
        restrict: 'AE',
        scope: {
            showTimer: '=',
            timeout: '='
        },
        link: function(scope, element, attrs){
            scope.timer = false;
            scope.timerCount = scope.timeout / 1000;
            scope.text = "获取验证码";

            scope.onClick = function(){
                scope.showTimer = true;
                scope.timer = true;
                scope.text = 's';
                var counter = $interval(function(){
					if(scope.timerCount > 0) {
						scope.timerCount = scope.timerCount - 1;
					}else {
						scope.timerCount = '';
					}
                }, 1000);

                $timeout(function(){
                    scope.text = "重新获取";
                    scope.timer = false;
                    $interval.cancel(counter);
                    scope.showTimer = false;
                    scope.timerCount = scope.timeout / 1000;
                }, scope.timeout);
            }
        },
        template: ''
    };
});

angular.element(document).ready(function() {   
	angular.bootstrap(document,['myModule']);  
});

运行效果:

  刚打开页面,显示”获取验证码“按钮

  点击”获取验证码“按钮,进行秒倒计时

  倒计到0时,显示”重新获取“,此时,可点击“重新获取”按钮重新进行倒计时。

 

五.AngularJs $interval 和 $timeout

1.$interval

  window.setInterval的Angular包装形式。Fn是每次延迟时间后被执行的函数。

  间隔函数的返回值是一个承诺。这个承诺将在每个间隔刻度被通知,并且到达规定迭代次数后被取消,如果迭代次数未定义,则无限制的执行。通知的值将是运行的迭代次数。取消一个间隔,调用$intreval.cancel(promise)。

  备注:当你执行完这项服务后应该把它销毁。特别是当controller或者directive元素被销毁时而$interval未被销毁。你应该考虑到在适当的时候取消interval事件。

使用:$interval(fn,delay,[count],[invokeApply],[Pass]);

  fn:一个将被反复执行的函数。

  delay:每次调用的间隔毫秒数值。

  count:循环次数的数值,如果没设置,则无限制循环。

  invokeApply:如果设置为false,则避开脏值检查,否则将调用$apply。

  Pass:函数的附加参数。

方法:cancel(promise);

  取消与承诺相关联的任务。

  promise:$interval函数的返回值。

使用代码:

(function () {
    angular.module("Demo", [])
    .controller("testCtrl",["$interval",testCtrl]);
    function testCtrl($interval){
      var toDo = function () {
          console.log("Hello World");
      };
      $interval(toDo, 3000, 10);
    };
  }());

2.$timeout

  window.setTimeout的Angular包装形式。Fn函数包装成一个try/catch块,代表$exceptionHandler服务里的任何异常。

  timeout函数的返回值是一个promise,当到达设置的超时时间时,这个承诺将被解决,并执行timeout函数。

  需要取消timeout,需要调用$timeout.cancel(promise);

使用: $timeout(fn,[delay],[invokeApply]);

  fn:一个将被延迟执行的函数。

  delay:延迟的时间(毫秒)。

  invokeApply:如果设置为false,则跳过脏值检测,否则将调用$apply。

方法:cancel(promise);

  取消与承诺相关联的任务。这个的结果是,承诺将被以摒弃方式来解决。

  promise:$timeout函数返回的承诺。

使用代码:

(function () {
    angular.module("Demo", [])
    .controller("testCtrl",["$timeout",testCtrl]);
    function testCtrl($timeout){
      var toDo = function () {
          console.log("Hello World");
      };
      $timeout(toDo,5000)
    };
  }());

  大致使用方法可以和原生js的setInterval和setTimeout那样使用,一些使用小技巧可以用在浏览器单线程的事件执行方面。

  • angularjs短信验证码及秒倒计时_第1张图片
  • 大小: 3.2 KB
  • angularjs短信验证码及秒倒计时_第2张图片
  • 大小: 3.9 KB
  • angularjs短信验证码及秒倒计时_第3张图片
  • 大小: 1.2 KB
  • angularjs短信验证码及秒倒计时_第4张图片
  • 大小: 1.6 KB
  • angularjs短信验证码及秒倒计时_第5张图片
  • 大小: 789 Bytes
  • angularjs短信验证码及秒倒计时_第6张图片
  • 大小: 1.3 KB
  • Angualr秒倒计时.rar (110 KB)
  • 下载次数: 1
  • 查看图片附件

你可能感兴趣的:(angular,$interval,setTimeout)