页面滚动时加载角度视图和控制器太慢
Lazy loading Angular views and controllers on page scroll
我有一个使用Laravel和Angular的微型网站。这是一个一页的微型网站,反应迅速,分为5个部分。我想懒洋洋地装上它们,一次减少装载量。
<body ng-app>
<div id="wrapper">
<section id="intro">1</section>
<section id="Second">2</section>
<section id="Third">3</section>
<section id="Fourth">4</section>
<section id="Fifth">5</section>
</div>
</body>
我正在寻找加载1&2在页面加载时,当你向下滚动页面时,加载另一个具有良好淡入效果的视图,然后加载其交互式项目。
在这种情况下,延迟加载控制器可能没有必要(或没有效率),但可以做到。
这里有很多事情需要处理,所以我将分部分处理。
滚动时缓慢加载视图(已设置动画)
此处的实时演示(单击)
标记:
<div class="container">
<section
ng-repeat="section in loadedSections"
ng-include="section+'.html'"
scroll-load
scroll-load-from="sections"
scroll-load-to="loadedSections"
ng-animate="{enter:'section-animate-enter'}"
></section>
</div>
动画CSS:
.section-animate-enter {
-webkit-transition: 1.5s linear all;
transition: 1.5s linear all;
opacity: 0;
left: 100%;
}
.section-animate-enter.section-animate-enter-active {
opacity: 1;
left: 0;
}
角度逻辑:
app.controller('myCtrl', function($scope) {
$scope.sections = ['top','mid','bottom']; //html files to load (top.html, etc)
$scope.loadedSections = [$scope.sections[0]]; //loaded html files
});
app.directive('scrollLoad', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var to = scope[attrs.scrollLoadTo]; //$scope.loadedSections
var from = scope[attrs.scrollLoadFrom]; //$scope.sections
$window = angular.element(window);
$window.bind('scroll', function(event) {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollPos = scrollTop + document.documentElement.clientHeight;
var elemBottom = element[0].offsetTop + element.height();
if (scrollPos >= elemBottom) { //scrolled to bottom of scrollLoad element
$window.unbind(event); //this listener is no longer needed.
if (to.length < from.length) { //if there are still elements to load
//use $apply because we're in the window event context
scope.$apply(to.push(from[to.length])); //add next section
}
}
});
}
};
});
懒惰加载控制器和滚动视图(动画)
此处的实时演示(单击)
标记:
<div class="container">
<!-- the "lazy" directive will get the controller first, then add ng-include -->
<section
ng-repeat="section in loadedSections"
lazy="section"
scroll-load
scroll-load-from="sections"
scroll-load-to="loadedSections"
ng-animate="{enter:'section-animate-enter'}"
></section>
</div>
角度逻辑:
var $appControllerProvider; //see below
var app = angular.module('myApp', []);
app.config(function($controllerProvider) {
$appControllerProvider = $controllerProvider; //cache this so that we can lazy load controllers
});
app.controller('myCtrl', function($scope) {
$scope.sections = ['top','mid','bottom']; //html files to load (top.html, etc)
$scope.loadedSections = [$scope.sections[0]]; //loaded html files
});
app.directive('scrollLoad', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var to = scope[attrs.scrollLoadTo]; //$scope.loadedSections
var from = scope[attrs.scrollLoadFrom]; //$scope.sections
$window = angular.element(window);
$window.bind('scroll', function(event) {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollPos = scrollTop + document.documentElement.clientHeight;
var elemBottom = element[0].offsetTop + element.height();
if (scrollPos >= elemBottom) { //scrolled to bottom of scrollLoad element
$window.unbind(event); //this listener is no longer needed.
if (to.length < from.length) { //if there are still elements to load
//use $apply because we're in the window event context
scope.$apply(to.push(from[to.length])); //add next section
}
}
});
}
};
});
app.factory('myService', function($http, $q) {
return {
getController: function(fileName) {
return $http.get(fileName+'.js').then(function(response) {
return response.data;
});
}
}
});
app.directive('lazy', function(myService, $compile, $q) {
/* I store the directive in a variable then return it later
* so that I can abstract directive logic into other functions below */
var directiveReturn = {
restrict: 'A',
link: function(scope, element, attrs) {
var loadName = scope.$eval(attrs.lazy);
//this is straightforward - see the "addScript" function for explanation
myService.getController(loadName).then(function(js) {
return addScript(loadName, js, scope);
}).then(function() {
//the controller has been lazy loaded into angular
//now use "ng-include" to lazy load the view.
var ngInc = angular.element('<span></span>')
.attr('ng-include', "'"+loadName+".html'")
.attr('ng-controller', loadName+'Ctrl');
element.append(ngInc);
$compile(ngInc)(scope);
});
} //link
}; //directive return
/*
* This is the magic.
*/
var scriptPromises = {};
function addScript(loadName, js, scope) {
if (!scriptPromises[loadName]) { //if this controller hasn't already been loaded
var deferred = $q.defer();
//cache promise (which caches the controller when resolved)
scriptPromises[loadName] = deferred.promise;
//inject controller into a script tag
var script = document.createElement('script');
script.src = 'data:text/javascript,' + encodeURI(js);
script.onload = function() {
//this is how you lazy load a controller
$appControllerProvider.register(loadName, window[loadName+'Ctrl']);
//now that the controller is registered with angular, resolve the promise
//then, it is safe to add markup that uses this controller with ng-controller
scope.$apply(deferred.resolve());
};
//when this script loads, the controller will be registered and promise is resolved
document.body.appendChild(script);
return deferred.promise;
}
else { //controller already loaded
return scriptPromises[loadName]; //use cached controller
}
}
return directiveReturn;
});
相关文章:
- 将范围添加到角度种子默认视图控制器时,测试套件现在失败
- 设置子视图控制器 EmberJS
- 使用emberjs测试视图控制器
- UIwebview图片到新的视图控制器
- 节点.js中的模型-视图-控制器模式
- 如何通过不同的视图/控制器在特定元素上设置 ng-show
- Extjs 5.1:视图控制器中的方法未调用
- 视图控制器和恩约
- 如何在路由更改之间维护视图(控制器)状态
- 角度.js分页过滤的数据并显示总项目,而无需在视图/控制器中复制代码
- 嵌套视图控制器和ng-click-AngularJs
- 视图/控制器不会使用 push() 函数刷新,使用 angularjs 中的 socket.io
- 如何在状态管理器视图控制器中传递已解析的依赖项
- 建议:在JavaScript中难以使用模型视图控制器
- 在Angular JS中动态加载视图/控制器
- 如何将数据从主控制器发射到角度视图控制器
- 如何在Rails视图控制器中访问HTML5本地存储
- 在Angular中,如何重新初始化视图'控制器中的$scope变量?
- 跨视图控制器传输值不工作
- 视图控制器需要:属性不工作