使用AngularJS单页面应用程序集成Skrollr

时间:2014-05-17 19:35:46

标签: javascript angularjs skrollr

我使用AngularJS设置了单页应用,并在home页面上使用了Skrollr。我之前没有使用过Skrollr,所以我想和其他人一起检查一下正确的' Angular'在我开始使用更多功能

之前,将它与AngularJS集成的方法

我在Angular中所做的是创建一个服务,将脚本加载到页面上并调用skrollr.init()并将其作为承诺返回。然后将服务注入指令,根据需要调用refresh。如果页面需要skrollr,我可以在某处的页面上使用该指令,并为每个skrollr文档设置data属性。

即这有效:

<div class="main" skrollr-tag>
    <div data-0="color:rgb(0,0,255);" data-90="color:rgb(255,0,0);">WOOOT</div>
</div>

似乎元素稍后添加到DOM中,例如通过ngRepeat,skrollr不知道,所以我需要在动态生成的所有元素上包含此指令w / skrollr data属性工作

<div class="main" skrollr-tag> 
    <!-- this heading will animate all the time -->
    <h1 data-0="opacity: 1" data-50="opacity: 0">WOOT!</h1>
    <div data-ng-repeat="item in items" class="had-to-add-skrollr-again" skrollr-tag> 
        <!-- skrollr animates this only on page refresh, unless skrollr-tag duplicated above -->
        <div data-0="color:rgb(0,0,255);" data-90="color:rgb(255,0,0);">{{item.name}}</div>
    </div>
</div>

所以,回顾一下,skrollr意识到&#39;刷新后第一次加载时的这些动态元素,然后再导航到不同的路径,然后再次返回,除非再次刷新页面,或者向动态元素本身添加skrollr-tag指令,否则它们不再动画。

出于性能原因,在每个需要skrollr的动态元素上包含此指令是不是一个坏主意,因此为每个动态元素再次调用refresh()?理想情况下,解决方案是每页加载skrollr-tag指令一次,并且它知道动态元素。我愿意接受任何完全不同的更简洁的方法来将skrollr集成到angular。

角度代码在这里:

服务:

.service('skrollrService', ['$document', '$q', '$rootScope', '$window', 
    function($document, $q, $rootScope, $window){
        var defer = $q.defer();

        function onScriptLoad() {
            // Load client in the browser
            $rootScope.$apply(function() { 
                var s = $window.skrollr.init({
                        forceHeight: false
                    });
                defer.resolve(s); 
            });
        }

        // Create a script tag with skrollr as the source
        // and call our onScriptLoad callback when it
        // has been loaded

        var scriptTag = $document[0].createElement('script');
        scriptTag.type = 'text/javascript'; 
        scriptTag.async = true;
        scriptTag.src = 'lib/skrollr/dist/skrollr.min.js';

        scriptTag.onreadystatechange = function () {
            if (this.readyState === 'complete') onScriptLoad();
        };

        scriptTag.onload = onScriptLoad;

        var s = $document[0].getElementsByTagName('body')[0];
        s.appendChild(scriptTag);

        return {
            skrollr: function() { return defer.promise; }
        };

    }
 ]);

指令:

.directive('skrollrTag', [ 'skrollrService', 
    function(skrollrService){
        return {
            link: function(){
                skrollrService.skrollr().then(function(skrollr){
                    skrollr.refresh();
                });
            }
        };
    }
])

3 个答案:

答案 0 :(得分:0)

这个答案应该有所帮助:AngularJS watch DOM change。尝试更新您的指令以监视子节点更改。这样,只要添加新节点,它就会自动刷新。

.directive('skrollrTag', [ 'skrollrService', 
    function(skrollrService){
        return {
            link: function(scope, element, attrs){
                skrollrService.skrollr().then(function(skrollr){
                    skrollr.refresh();
                });

               //This will watch for any new elements being added as children to whatever element this directive is placed on. If new elements are added, Skrollr will be refreshed (pulling in the new elements
               scope.$watch(
                   function () { return element[0].childNodes.length; },
                   function (newValue, oldValue) {
                   if (newValue !== oldValue) {
                       skrollrService.skrollr().then(function(skrollr){
                           skrollr.refresh();
                       });
                   }
               });
            }
        };
    }
]);

修改

更新以说明您正在使用的承诺(已经解决),并添加了评论以进一步解释该解决方案。

答案 1 :(得分:0)

我目前正在尝试将Skrollr集成到AngularJS中。

问题基本上就是这个指令,它在第一次加载页面时起作用,但是即使在创建新的html元素时调用它或者当你更改视图时也没有发生任何事情。

.directive('skrollrTag', [ 'skrollrService', 
function(skrollrService){
    return {
        link: function(){
            skrollrService.skrollr().then(function(skrollr){
                skrollr.refresh();
            });
        }
    };
}

])

我认为原因是angularJS注入新的html内容的方式。当skrollr“刷新”它尚未呈现或某种冲突时。 也许唯一的解决方案是修改skrollr脚本。

答案 2 :(得分:0)

我为 skrollr

制定了指令
(function () {
  'use strict';
  angular.module('myApp', [])
    .directive('skrollr', function () {
      var obj = {
        link: function () {
          /* jshint ignore:start */
          skrollr.init().refresh();
          /* jshint ignore:end */
        }
      };
      return obj;
    });
})();

并像这样使用

<div skrollr data-0="background-color:rgb(0,0,255);" data-500="background-color:rgb(255,0,0);">WOOOT</div>