首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AngularJS :指令:为滑动页面设置动画并推迟控制器绑定

AngularJS :指令:为滑动页面设置动画并推迟控制器绑定
EN

Stack Overflow用户
提问于 2013-08-04 22:51:26
回答 1查看 1.5K关注 0票数 4

我正在试图弄清楚如何推迟默认的控制器绑定,并且只在指令中应用它,一旦在带有内容的DOM元素上执行了特定的动画(自定义-而不是angularjs动画)。我想要完成的工作是在这里,尽管它确实在滑动动画完成之前立即替换了内容:http://jsfiddle.net/scabro/hHy7s/27/

我需要能够推迟$scope绑定,直到页面容器完成向上滑动/动画,然后用控制器中的数据替换内容,一旦完成,就向下滑动。

这是我目前所拥有的:

HTML:

代码语言:javascript
复制
<div id="wrapper" ng-app="myApp">

    <div page-animate>

        <p>
            <a class="btn btn-primary" href="#/" ng-click="slidePage()">Home</a>
            <a class="btn btn-info" href="#/users" ng-click="slidePage()">Users</a>
            <a class="btn btn-success" href="#/pages" ng-click="slidePage()">Pages</a>
        </p>
        <div id="relativeContainer">

            <div id="content" ng-view=""></div>

        </div>

    </div>

</div>

CSS:

代码语言:javascript
复制
#wrapper {
    text-align:center;
    padding:30px 0;
}
#relativeContainer {
    text-align:left;
    position: relative;
    width: 500px;
    height: 800px;
    min-height: 800px;
    margin: 0 auto;
    overflow: hidden;
}
#content {
    position: absolute;
    top: 0;
    left: 0;
}

JS:

代码语言:javascript
复制
var myApp = angular.module('myApp', []);

myApp.directive('pageAnimate', function() {

    return {

        restrict: 'A',

        scope: { },

        link: function (scope, elem, attrs) {

            scope.slidePage = function() {

                var thisContainer = $('#content');

                var thisHeight = thisContainer.outerHeight();

                thisContainer.animate({ top : '-' + thisHeight + 'px'}, { duration : 300, complete : function() {

                    thisContainer.css({ top : '-999999em' });

                    var thisNewHeight = thisContainer.outerHeight();

                    $('#relativeContainer').animate({ height : thisNewHeight + 'px' }, { duration : 200, complete : function() {

                        thisContainer.css({ top : '-' + thisNewHeight + 'px' }).animate({ top : 0 }, { duration : 300 });

                    }});

                }});

            };

        }

    }

});


myApp.config(function($routeProvider) {

    $routeProvider
        .when('/',
            {
                controller: 'HomeController',
                template: '<h1>{{ heading }}</h1><p>{{ content }}</p>'
            }
        )
        .when('/users',
            {
                controller: 'UserController',
                template: '<h1>{{ heading }}</h1><p>{{ content }}</p>'
            }
        )
        .when('/pages',
            {
                controller: 'PageController',
                template: '<h1>{{ heading }}</h1><p>{{ content }}</p>'
            }
        )
        .otherwise(
            {
                redirectTo: '/'
            }
        )

});

myApp.controller('HomeController', function($scope) {

    $scope.heading = 'Home page';
    $scope.content = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate';

});

myApp.controller('UserController', function($scope) {

    $scope.heading = 'Users';
    $scope.content = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.';

});

myApp.controller('PageController', function($scope) {

    $scope.heading = 'Pages';
    $scope.content = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';

});
EN

回答 1

Stack Overflow用户

发布于 2013-08-09 17:34:59

首先,做一些最小的改动来让你的代码正常工作。您需要阻止默认事件导航页面(这就是它在导航完成之前更改的原因),并且需要在第一个动画完成后手动执行导航。因此,一种方法是将事件和url传递到slidePage

代码语言:javascript
复制
<div id="wrapper" ng-app="myApp">
    <div page-animate>
        <p>
            <a class="btn btn-primary"  ng-click="slidePage($event, '/')">Home</a>
            <a class="btn btn-info" ng-click="slidePage($event, '/users')">Users</a>
            <a class="btn btn-success" ng-click="slidePage($event, '#/pages')">Pages</a>
        </p>
        <div id="relativeContainer">

            <div id="content" ng-view=""></div>
        </div>
    </div>
</div>

slidePage本身就变成了:

代码语言:javascript
复制
        scope.slidePage = function(event, url) {
            event.preventDefault();
            event.stopPropagation();
            var thisContainer = $('#content');

            var thisHeight = thisContainer.outerHeight();

            thisContainer.animate({ top : '-' + thisHeight + 'px'}, { duration : 300, complete : function() {
                thisContainer.css({ top : '-999999em' });
                $location.url(url);
                scope.$apply();

                var thisNewHeight = thisContainer.outerHeight();

                $('#relativeContainer').animate({ height : thisNewHeight + 'px' }, { duration : 200, complete : function() {

                    thisContainer.css({ top : '-' + thisNewHeight + 'px' }).animate({ top : 0 }, { duration : 300 });

                }});

            }});

这段代码应该像你想要的那样工作,但我认为它并不完全遵循angular的哲学。

相反,我认为您应该直接添加一个slidePage指令,这样链接就是<a href='#/pages' slide-page>。该指令可以访问属性(因此它可以获取href),并且可以将click处理程序直接绑定到锚元素上。我还可以通过用另一个指令标记要进行动画处理的元素来删除#content元素的硬连接。然而,同样的基本原理也适用:停止事件传播,执行第一个动画,然后在执行第二个动画之前更新位置。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18044220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档