我是棱角分明的新手,我正试图解决这个问题,尽管我现在仍然坚持在基于内容的旋转木马内部动画内容。我自己制作了这个旋转木马,但我没有考虑“幻灯片”之间的淡化内容会如何预先发挥作用。
目前我的轮播结构是:
<article class="container-fluid carousel-container" ng-controller="carouselController">
<div class="container">
<div class="prev-container">
<button class="prev" ng-click="prevSlide()"><span>‹</span></button>
</div>
<div class="slide">
<div class="slide-left">
<h1 class="slide-inner" ng-cloak>{{panels[slide].title}}</h1>
<p class="slide-inner" ng-cloak>{{panels[slide].body}}</p>
</div>
</div>
<div class="next-container">
<button class="next" ng-click="nextSlide()"><span>›</span></button>
</div>
</div>
</article>
我只是更改单个“幻灯片”的内容,而不是使用实际的幻灯片。稍后我将在slide-right
容器中添加图像。
此功能位于carouselController
:
app.controller('carouselController', function($scope){
$scope.slide = 0;
$scope.prevSlide = function(){
if ($scope.slide <= 0) {
$scope.slide = ($scope.panels.length - 1);
} else {
$scope.slide--;
};
};
$scope.nextSlide = function(){
if ($scope.slide >= $scope.panels.length - 1) {
$scope.slide = 0;
} else {
$scope.slide++;
};
};
$scope.panels = [
{
id: 1,
title: "1 - Lorem ipsum",
body: "1 - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus, dolores voluptas quod fuga id nihil in! Dolore accusantium perferendis deleniti voluptate, libero quis at molestias."
},
{
id: 2,
title: "2 - Lorem ipsum",
body: "2 - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus, dolores voluptas quod fuga id nihil in! Dolore accusantium perferendis deleniti voluptate, libero quis at molestias."
},
{
id: 3,
title: "3 - Lorem ipsum",
body: "3 - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus, dolores voluptas quod fuga id nihil in! Dolore accusantium perferendis deleniti voluptate, libero quis at molestias."
}
];
});
这里的基本思想是从panels
数组填充内容,单击下一个按钮或prev按钮将分别递增或递减数组索引。然后填充slide-left
div中的标题和正文内容。我遇到的问题是当使用next或prev按钮时,我想淡出那里的内容,淡入新内容。我尝试了addClass
和removeClass
,还有许多其他没有结果的方法。最大的障碍是我实际上并没有改变幻灯片和内容,因为大多数资源和教程假设我隐藏了一张幻灯片,并揭示了下一张幻灯片。我期待着您的建议并感谢您的帮助,并随时批评我现有的代码。
答案 0 :(得分:3)
如果您想构建一个淡入/淡出过渡的轮播并避免使用ngAnimate,这里有一种方法涉及创建一组自定义指令。
工作示例:JSFiddle
以下是HTML使用此方法的样子:
<div ng-controller="MyController as vm">
<carousel panels="vm.panels">
<carousel-panel>
<h1>{{$title}}</h1>
<p>{{$body}}</p>
</carousel-panel>
<button carousel-prev>
‹ Prev
</button>
<button carousel-next>
Next ›
</button>
</carousel>
</div>
请注意,使用了四(4)个指令:
第一个carousel
是一个包装器,需要作为其他元素的父元素。这使得每个子组件都可以与carousel
的控制器进行交互,同时明确区分每个组件的关注点,而不会创建任何隐藏的依赖关系。
该指令有一个控制器,它向需要它的子指令公开数据和功能。它有一个panels
属性,它是panels
属性的双向绑定。它还具有slide
属性,可以跟踪哪个面板可见;以及用于调整该值的next()
和prev()
函数。
angular.module('myApp.carousel')
.controller('CarouselController', CarouselController)
.directive('carousel', carouselDirective)
;
function CarouselController() {
var carousel = this;
carousel.slide = 0;
carousel.current = function() {
if (carousel.panels && carousel.panels.length) {
return carousel.panels[carousel.slide];
}
};
carousel.next = function() {
if (carousel.panels && carousel.panels.length) {
if (carousel.slide >= carousel.panels.length - 1) {
carousel.slide = 0;
} else {
carousel.slide++;
}
}
};
carousel.prev = function() {
if (carousel.panels && carousel.panels.length) {
if (carousel.slide <= 0) {
carousel.slide = carousel.panels.length - 1;
} else {
carousel.slide--;
}
}
};
}
function carouselDirective() {
return {
bindToController: {
panels: '='
},
controller: 'CarouselController',
controllerAs: 'carousel',
scope: true,
template: '<ng-transclude></ng-transclude>',
transclude: true
};
}
此指令监视其父slide
的{{1}}属性,并在该值发生更改时向其自身添加CarouselController
类。然后它设置超时(在此示例中硬编码为500ms)并在延迟过去时删除.fade
类。这适用于纯CSS过渡,如下所述。
.fade
这两个指令可以作为属性添加到按钮或任何其他元素。他们添加了点击&#39;事件处理程序分别调用父angular.module('myApp.carousel')
.directive('carouselPanel', carouselPanelDirective)
;
function carouselPanelDirective($timeout) {
return {
link: postLink,
require: '^carousel',
template: '<ng-transclude></ng-transclude>',
transclude: true
};
function postLink(scope, iElement, iAttrs, carousel) {
scope.$watch(currentSlide, transition);
function currentSlide() {
return carousel.slide;
}
function fadeOut() {
iElement.addClass('fade');
}
function fadeIn() {
iElement.removeClass('fade');
}
function refresh() {
var current = carousel.current();
scope.$title = current.title;
scope.$body = current.body;
}
function transition(currentSlide, previousSlide) {
if (currentSlide === previousSlide) {
refresh();
} else {
fadeOut();
$timeout(function() {
refresh();
fadeIn();
}, 500);
}
}
}
}
的{{1}}和next()
函数。
prev()
这些CSS规则定位CarouselController
的已转换HTML内容,并使用angular.module('myApp.carousel')
.directive('carouselNext', carouselNextDirective)
.directive('carouselPrev', carouselPrevDirective)
;
function carouselNextDirective() {
return {
link: postLink,
require: '^carousel'
};
function postLink(scope, iElement, iAttrs, carousel) {
iElement.on('click', onClick);
scope.$on('$destroy', offClick);
function onClick() {
carousel.next();
scope.$apply();
}
function offClick() {
iElement.off('click', onClick);
}
}
}
function carouselPrevDirective() {
return {
link: postLink,
require: '^carousel'
};
function postLink(scope, iElement, iAttrs, carousel) {
iElement.on('click', onClick);
scope.$on('$destroy', offClick);
function onClick() {
carousel.prev();
scope.$apply();
}
function offClick() {
iElement.off('click', onClick);
}
}
}
应用CSS转换。请注意0.5s(或500ms)的转换时间,这与我们的面板carousel-panel
函数中的延迟相对应。
opacity
这可能看起来很多工作,但它比仅将逻辑构建到单个控制器中更具可重用性,可扩展性和可维护性。通过使用transclusion,您可以启用应用程序模板来指示布局(与指令模板相对应)。