脚本宝典收集整理的这篇文章主要介绍了

基于angular实现等待长操作时锁定页面

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

由于网络等各方面原因,有时执行一个ajax操作时有时需要等待比较长的时间,如果不进行特殊处理就无法知道当前操作的状态,严重影响用户体验。

比较常见的解决方案是执行可能的长操作前先打开一个蒙版,覆盖页面,通过动画指示当前页面处于执行状态,获得返回结果后在关闭蒙版。这种方式虽然可以很清晰的展现正在等待操作结果的状态,但是对于网络条件比较好,操作结果很快就返回的情况,会给用户造成一种页面闪烁的感觉,也会影响用户体验。

为了解决上面的问题,考虑利用angular的directive对执行长操作时需要进行控制的元素进行设置,实现以元素为单位进行页面状态的控制。

需要进行状态控制的元素有几类:1、input元素,执行长操作时它们应该处于disabled状态;2、button等发起操作的元素,它们应该出于disabled的状态,同时发起正在执行的长操作的元素应该出于running的状态,例如:通过动画。

实现思路如下:
1、定义directive,tms-lock

app = angular.module('app', []);
app.directive('tmsLock', function() {
    return {
        restrict: 'A',
        scope: {
            lock: '=tmsLock'
        },
        priority: 99,
        compile: function(tElem, tAttrs) {
            var originalFn, lockableFn;
            if (tAttrs.tmsLockPromoter === 'Y' && tAttrs.ngClick) {
                originalFn = tAttrs.ngClick;
                lockableFn = '__lockable__' + originalFn;
                tAttrs.ngClick = lockableFn;
            }
            return {
                pre: function(scope, iElem, iAttrs) {
                    if (lockableFn) {
                        scope.$parent[lockableFn.replace(/(.*)/, '')] = function() {
                            var eleIndicator = document.createElement('div');
                            eleIndicator.classList.add('indicator');
                            scope.lock = true;
                            iElem.addClass('tms-lock-running');
                            iElem.append(eleIndicator);
                            scope.$parent[originalFn.replace(/(.*)/, '')].apply(scope, arguments).then(function() {
                                scope.lock = false;
                                iElem.removeClass('tms-lock-running');
                                iElem[0].removeChild(eleIndicator);
                            });
                        };
                    }
                    scope.$watch('lock', function(locked) {
                        if (locked === true) {
                            iElem.addClass('tms-locked');
                            iAttrs.$set('disabled', true);
                        } else if (locked === false) {
                            iElem.removeClass('tms-locked');
                            iAttrs.$set('disabled', undefined);
                        }
                    });
                }
            }
        }
    }
});
app.controller('ctrl', ['$scope', '$q', '$timeout', function($scope, $q, $timeout) {
    $scope.lock = false;
    $scope.longFn = function() {
        var defer;
        defer = $q.defer();
        $timeout(function() {
            defer.resolve();
        }, 10000);
        return defer.promise;
    };
    $scope.otherFn = function() {
        // do nothing
    };
}]);

2、设置运行状态的样式

@keyframes tmsRunning{
    0%{transform:rotate(0deg);}
    12%{transform:rotate(45deg);}
    25%{transform:rotate(90deg);}
    37%{transform:rotate(135deg);}
    50%{transform:rotate(180deg);}
    62%{transform:rotate(225deg);}
    75%{transform:rotate(270deg);}
    87%{transform:rotate(315deg);}
    100%{transform:rotate(360deg);}
}
@-webkit-keyframes tmsRunning{
    0%{-webkit-transform:rotate(0deg);}
    12%{-webkit-transform:rotate(45deg);}
    25%{-webkit-transform:rotate(90deg);}
    37%{-webkit-transform:rotate(135deg);}
    50%{-webkit-transform:rotate(180deg);}
    62%{-webkit-transform:rotate(225deg);}
    75%{-webkit-transform:rotate(270deg);}
    87%{-webkit-transform:rotate(315deg);}
    100%{-webkit-transform:rotate(360deg);}
}
@-moz-keyframes tmsRunning{
    0%{-moz-transform:rotate(0deg);}
    12%{-moz-transform:rotate(45deg);}
    25%{-moz-transform:rotate(90deg);}
    37%{-moz-transform:rotate(135deg);}
    50%{-moz-transform:rotate(180deg);}
    62%{-moz-transform:rotate(225deg);}
    75%{-moz-transform:rotate(270deg);}
    87%{-moz-transform:rotate(315deg);}
    100%{-moz-transform:rotate(360deg);}
}
@-o-keyframes tmsRunning{
    0%{-o-transform:rotate(0deg);}
    12%{-o-transform:rotate(45deg);}
    25%{-o-transform:rotate(90deg);}
    37%{-o-transform:rotate(135deg);}
    50%{-o-transform:rotate(180deg);}
    62%{-o-transform:rotate(225deg);}
    75%{-o-transform:rotate(270deg);}
    87%{-o-transform:rotate(315deg);}
    100%{-o-transform:rotate(360deg);}
}
.btn.tms-lock-running {
    position: relative;
}
.btn.tms-lock-running .indicator::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 4px;
    bottom: 4px;
    width: 4px;
    margin-left: -2px;
    background: #333;
}
.btn.tms-lock-running .indicator {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -1em;
    margin-top: -1em;
    border-radius: 1em;
    width: 2em;
    height: 2em;
    border: 2px solid #333;
    background: #fff;
    animation: tmsRunning 1s infinite;
    -webkit-animation: tmsRunning 1s infinite;
    -moz-animation: tmsRunning 1s infinite;
    -o-animation: tmsRunning 1s infinite;
}

3、给需要锁定的元素添加属性

class='form-control' type='text' tms-lock="lock">
class='btn btn-default' tms-lock="lock" tms-lock-promoter="Y" ng-click="longFn()">long action
class='btn btn-default' tms-lock="lock" ng-click="otherFn()">other action

示例

其他仍在考虑的问题:1、是否允许用户主动解除页面锁定状态?2、是否需要对硬的页面导航操作,例如:后退,进行控制?

总结

以上是脚本宝典为你收集整理的

基于angular实现等待长操作时锁定页面

全部内容,希望文章能够帮你解决

基于angular实现等待长操作时锁定页面

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过