Angular.js 指令使用 stellar.js 多次使用 - 只有第一个有效
Angular.js directive using stellar.js used multiple times - only the first one works
我写了一个 angular.js 指令,它使用 stellar.js 来实现视差效果。当我一个接一个地多次调用同一个指令时,stellar.js 将只对第一个有效。
我读到 $.stellar('refresh');
在 DOM 中注入元素后应该重新初始化 stellar,但这对我没有影响。在 window 上调用 stellar 也没有任何效果。
这是我的指令代码:
angular.module('ClientApp')
.directive('parallaxModule', function () {
return {
templateUrl: 'views/parallax-module.html',
restrict: 'E',
scope: {
data: '='
},
controller: function() {
$(function(){
$(this).stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 50
});
});
}
};
});
我是这样使用指令的:
<parallax-module data="sectionData.para"></parallax-module>
<parallax-module data="sectionData.para"></parallax-module>
这是我的模板:
<div class="parallax-module" data-stellar-background-ratio="0.2">
<div class="wrapper" data-stellar-ratio="2.5">
<div class="title">{{data.title}}</div>
<div class="caption">{{data.caption}}</div>
</div>
</div>
$timeout
之所以有效,是因为应该应用 stellar 插件,而不是应用到每个视差元素,而是应用到滚动容器。在文档中的示例中,它应用于 window
:$(window).stellar();
因此,对于 $timeout
,代码 "waits" 摘要队列的末尾,当它被执行时,所有的指令都被加载。不幸的是,它不必要地为每个指令执行。
解决方案是将指令应用于容器。然后它变得如此简单:
.directive("parallaxContainer", function(){
return {
link: function(scope, element){
element.stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 0
});
}
}
})
此解决方案依赖于该容器中的 stellar-compatible 元素(例如 data-stellar-background-ratio
):
<body parallax-container>
<div data-stellar-background-ratio="0.2">
...
</div>
<div data-stellar-background-ratio="0.2">
...
</div>
</body>
编辑:
如果动态加载视差元素,上述代码将无法运行。这使事情有点复杂,但并不多。在这种安排中,我们需要负责触发插件的容器指令,以及将自己注册到容器并在加载时通知容器的实际视差元素指令。
element 指令可以使用 ng-include
在内容加载时获得通知。该指令使用 require: "^parallaxContainer"
.
app.directive('parallaxModule', function() {
return {
template: '<div ng-include="\'parallax-module.html\'" onload="notifyLoaded()"></div>',
restrict: 'E',
scope: {
data: '='
},
require: "^parallaxContainer",
link: {
pre: function(scope, element, attrs, parallaxContainer){
parallaxContainer.registerElement();
scope.notifyLoaded = parallaxContainer.notifyElementLoaded;
}
}
};
})
parallaxContainer
指令添加了一个控制器,该控制器公开了要注册和通知的方法。当所有 children 已加载
时,它会触发插件
app.directive("parallaxContainer", function() {
var parallaxElementCount = 0;
var parallaxElementLoaded = 0;
return {
controller: function($element){
this.registerElement = function(){
parallaxElementCount++;
};
this.notifyElementLoaded = function(){
parallaxElementLoaded++;
if (parallaxElementCount !== 0 && parallaxElementCount === parallaxElementLoaded){
$element.stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 0
});
}
}
},
}
})
请注意,stellar
在多次激活时不起作用(出于某种原因 - 也许在 stellar 文档中有一些关于此的信息),因此一旦触发,加载更多 child 元素不会改变任何东西。
我找到了一个解决方案:因为 stellar 不是 angular 框架的一部分,所以我必须使用 $apply() 来执行 stellar 表达式。但是由于 $digest 已经在我的指令中进行,所以我必须使用 $timeout 来在另一个摘要周期中调用 stellar() 。 $timeout 隐式调用 $apply。我还必须在 angular.element($window) 上调用 stellar() 才能正确获取多个指令 运行。
所以这是我的工作代码:
angular.module('ClientApp')
.directive('parallaxModule', function ($timeout, $window) {
return {
templateUrl: 'views/parallax-module.html',
restrict: 'E',
scope: {
data: '='
},
link: function() {
$timeout(function () {
angular.element($window).stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 50
});
});
}
};
});
Angular2/Angular4 使用 NG-PARALLAX 指令非常简单。
Link:https://www.npmjs.com/package/ng2-parallaxscroll
Git:https://github.com/tyrantwave/ng2-parallaxscroll
示例 1:
<div parallax [config]="{axis: x, speed: -.3}" style=" background-image: url('/parallax_img.jpg');"></div>
示例 2:
<ng-parallax img="img/img.jpg" [config]="{axis: x, speed: -.3}" class="some-class"></ng-parallax>
我写了一个 angular.js 指令,它使用 stellar.js 来实现视差效果。当我一个接一个地多次调用同一个指令时,stellar.js 将只对第一个有效。
我读到 $.stellar('refresh');
在 DOM 中注入元素后应该重新初始化 stellar,但这对我没有影响。在 window 上调用 stellar 也没有任何效果。
这是我的指令代码:
angular.module('ClientApp')
.directive('parallaxModule', function () {
return {
templateUrl: 'views/parallax-module.html',
restrict: 'E',
scope: {
data: '='
},
controller: function() {
$(function(){
$(this).stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 50
});
});
}
};
});
我是这样使用指令的:
<parallax-module data="sectionData.para"></parallax-module>
<parallax-module data="sectionData.para"></parallax-module>
这是我的模板:
<div class="parallax-module" data-stellar-background-ratio="0.2">
<div class="wrapper" data-stellar-ratio="2.5">
<div class="title">{{data.title}}</div>
<div class="caption">{{data.caption}}</div>
</div>
</div>
$timeout
之所以有效,是因为应该应用 stellar 插件,而不是应用到每个视差元素,而是应用到滚动容器。在文档中的示例中,它应用于 window
:$(window).stellar();
因此,对于 $timeout
,代码 "waits" 摘要队列的末尾,当它被执行时,所有的指令都被加载。不幸的是,它不必要地为每个指令执行。
解决方案是将指令应用于容器。然后它变得如此简单:
.directive("parallaxContainer", function(){
return {
link: function(scope, element){
element.stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 0
});
}
}
})
此解决方案依赖于该容器中的 stellar-compatible 元素(例如 data-stellar-background-ratio
):
<body parallax-container>
<div data-stellar-background-ratio="0.2">
...
</div>
<div data-stellar-background-ratio="0.2">
...
</div>
</body>
编辑:
如果动态加载视差元素,上述代码将无法运行。这使事情有点复杂,但并不多。在这种安排中,我们需要负责触发插件的容器指令,以及将自己注册到容器并在加载时通知容器的实际视差元素指令。
element 指令可以使用 ng-include
在内容加载时获得通知。该指令使用 require: "^parallaxContainer"
.
app.directive('parallaxModule', function() {
return {
template: '<div ng-include="\'parallax-module.html\'" onload="notifyLoaded()"></div>',
restrict: 'E',
scope: {
data: '='
},
require: "^parallaxContainer",
link: {
pre: function(scope, element, attrs, parallaxContainer){
parallaxContainer.registerElement();
scope.notifyLoaded = parallaxContainer.notifyElementLoaded;
}
}
};
})
parallaxContainer
指令添加了一个控制器,该控制器公开了要注册和通知的方法。当所有 children 已加载
app.directive("parallaxContainer", function() {
var parallaxElementCount = 0;
var parallaxElementLoaded = 0;
return {
controller: function($element){
this.registerElement = function(){
parallaxElementCount++;
};
this.notifyElementLoaded = function(){
parallaxElementLoaded++;
if (parallaxElementCount !== 0 && parallaxElementCount === parallaxElementLoaded){
$element.stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 0
});
}
}
},
}
})
请注意,stellar
在多次激活时不起作用(出于某种原因 - 也许在 stellar 文档中有一些关于此的信息),因此一旦触发,加载更多 child 元素不会改变任何东西。
我找到了一个解决方案:因为 stellar 不是 angular 框架的一部分,所以我必须使用 $apply() 来执行 stellar 表达式。但是由于 $digest 已经在我的指令中进行,所以我必须使用 $timeout 来在另一个摘要周期中调用 stellar() 。 $timeout 隐式调用 $apply。我还必须在 angular.element($window) 上调用 stellar() 才能正确获取多个指令 运行。
所以这是我的工作代码:
angular.module('ClientApp')
.directive('parallaxModule', function ($timeout, $window) {
return {
templateUrl: 'views/parallax-module.html',
restrict: 'E',
scope: {
data: '='
},
link: function() {
$timeout(function () {
angular.element($window).stellar({
horizontalScrolling: false,
verticalScrolling: true,
verticalOffset: 50
});
});
}
};
});
Angular2/Angular4 使用 NG-PARALLAX 指令非常简单。
Link:https://www.npmjs.com/package/ng2-parallaxscroll
Git:https://github.com/tyrantwave/ng2-parallaxscroll
示例 1:
<div parallax [config]="{axis: x, speed: -.3}" style=" background-image: url('/parallax_img.jpg');"></div>
示例 2:
<ng-parallax img="img/img.jpg" [config]="{axis: x, speed: -.3}" class="some-class"></ng-parallax>