English

Blog

Делаем простой slider ( slide show ) на AngularJS

Categories: Web Development

Сейчас большинство приложений выполняются на различных javascript фреймворках и зачастую становится очень не удобно использовать уже давно знакомые jQuery слайдеры или карусели. Гораздо проще будет написать плагин, работающий посредством самого фреймворка. Ниже приставлен простой способ самому написать плагин слайд шоу или слайдер на angularJS без единой строчки jQuery. Используем angular директивы и angular анимацию для этой цели. Если вы не знакомы с этим фреймворком посмотрите русскую документацию или английскую документацию angular.

Шаг 1: Написание директивы слайдера

Когда дело доходит до AngularJS в первую очередь нужно задумать о проектировании приложения, а затем оформлять соответствующей разметкой и дизайном. Так как мы хотим что бы наш слайдер легко подключался к существующему AngularJS приложению, то создать слайдер через директиву будет правильным решением. И там директива по имени ‘slider':

var sliderApp = angular.module('sliderApp', []);

sliderApp.directive('slider', function($timeout) {
return {
restrict: 'AE',
replace: true,
scope: {
images: '='
},
link: function(scope, elem, attrs) {},
templateUrl: 'templates/templateurl.html'
};
});

Важно отметить, что мы выделили область видимости директивы. Поскольку нам потребуется несколько функций для внутреннего использования, правильнее будет использовать изолированную область видимости мы не будет засорять родительскую область. Кроме того, нужно быть в состоянии принять список изображений из родительской области для отображения. Вот почему мы используем «=». Наконец для удобства, шаблон директивы идет внутри файла templateurl.html.

Шаг 2: Настройка контроллера

Далее, давайте создадим контроллер, который создает массив из пяти объектов изображения в его scope. Мы будем передавать эти изображения в директиву позже.

sliderApp.controller('SliderController', function($scope) {
$scope.images = [{
src: 'img1.png',
alt: 'Pic 1'
}, {
src: 'img2.jpg',
alt: 'Pic 2'
}, {
src: 'img3.jpg',
alt: 'Pic 3'
}, {
src: 'img4.png',
alt: 'Pic 4'
}, {
src: 'img5.png',
alt: 'Pic 5'
}];
});

Шаг 3: Разметка директивы

Чтобы отобразить весь массив изображений мы будем использовать ng-repeat. Так же сделаем навигацию с кнопками вперед и назад. Содержание шаблона templateurl.html показана ниже.

<div class="slider">
<div class="slide" ng-repeat="image in images" ng-show="image.visible">
<img ng-src="img/{{image.src}}" alt="{{image.alt}}" />
</div>
<div class="arrows">
<a href="#" ng-click="prev()">
<img src="img/left-arrow.png" />
</a>
<a href="#" ng-click="next()">
<img src="img/right-arrow.png" />
</a>
</div>
</div>

Разметка довольно простая, ng-repeat и ng-src показывает все изображения. Свойство image.visible будет отображать видимое, передав в него true и скрывать остальные изображения, задав false, при помощи ng-show. Навигация при клике вызывает функции вперед и назад. можно так же добавить image.title или image.atr если это необходимо.

Шаг 4: Наполнение директивы

Нужно будет следить за видимым изображением и для это бы будет использовать свойство currentIndex в изолированной области видимости директивы. Так же нужно будет реализовать функции вперед, которая будет увеличивать currentIndex и назад для уменьшения, а так же функцию показ определенного слайда.

scope.currentIndex = 0; // Initially the index is at the first image

scope.next = function() {
scope.currentIndex < scope.images.length - 1 ? scope.currentIndex++ : scope.currentIndex = 0;
};

scope.prev = function() {
scope.currentIndex > 0 ? scope.currentIndex-- : scope.currentIndex = scope.images.length - 1;
};
scope.getslide= function(index) {
scope.currentIndex = index;
};

Функции позволят переключать слайды, например при нажатии на кнопки, или можно придумать что-нибудь посложнее. Но нам нужно будет определить когда происходит это изменение и сделать соответственное изображение видимым, передав в нужный image.visible значение true. Сделать это можно так:

scope.$watch('currentIndex', function() {
scope.images.forEach(function(image) {
image.visible = false; // make every image invisible
});

scope.images[scope.currentIndex].visible = true; // make the current image visible
});

Шаг 5: Анимация слайдера

В angular 1.2 введена новая структура анимации, которую можно использовать чтобы сделать плавную CSS3 анимацию по событию. Нужно просто указать анимацию а angular позаботиться обо всем остальном. Angular будет автоматически добавлять и удалять классы и достаточно написать CSS для этих классов. Чтобы подключить анимацию нужно добавить модуль ngAnimate:

var sliderApp = angular.module('sliderApp', ['ngAnimate']);

При этом нужно не забыть подключить сам модуль:

<script src="http://code.angularjs.org/1.2.9/angular-animate.min.js"></script>

И собственно задать стили:

.slide.ng-hide-add,
.slide.ng-hide-remove {
-webkit-transition: all linear 0.5s;
-moz-transition: all linear 0.5s;
-o-transition: all linear 0.5s;
transition: all linear 0.5s;
display: block!important;
}
.slide.ng-hide-add.ng-hide-add-active,
.slide.ng-hide-remove {
opacity: 0;
}
.slide.ng-hide-add,
.slide.ng-hide-remove.ng-hide-remove-active {
opacity: 1;
}

Шаг 6: Использование директивы

Теперь пришло время, чтобы использовать директиву в HTML. Так же с помощью директивы мы должны передать массив изображений, объявленный в контроллере к директиве.

<body ng-controller="SliderController">
<h1>Slider Using AngularJS</h1>
<slider images="images" />
</body>

Самый простой слайдер готов. Осталось задать немного стилей для страницы.

.slider {
position: relative;
padding: 5px;
width: 610px;
margin: auto;
margin-top: 40px;
}
.slide {
position: absolute;
top: 0;
left: 0;
box-shadow: 0px 0px 15px #999;
}
.arrows {
position: absolute;
top: 10px;
right: 20px;
}
.arrows img {
height: 32px;
}
h1 {
text-align: center;
padding: 10px;
font-size: 40px;
color: #222;
}

Бонус

В дополнение можно так же просто сделать чтобы наш слайдер автоматически листал к следующему изображению. Для этого мы можем использовать сервис Angular $timeout:

sliderApp.directive('slider', function($timeout) {
...
// configuarations here
...
var timer;
var sliderFunc = function() {
timer = $timeout(function() {
scope.next();
timer = $timeout(sliderFunc, 5000);
}, 5000);
};

sliderFunc();

scope.$on('$destroy', function() {
$timeout.cancel(timer); // when the scope is getting destroyed, cancel the timer
});
});

Вместо заключения

Вот так просто даже при небольших знаниях ангуляра создать слайдер или slide show. Так же вы можете посмотреть demo.