Эффект затухания для вкладок в ui-bootstrap (Angular.JS)
Как добавить анимацию fade в tabset с помощью angular -ui-bootstrap?
Например, учитывая следующий код:
<tabset>
<tab heading="Tab1">Some content</tab>
<tab heading="Tab2">Other content</tab>
</tabset>
Я хочу, чтобы содержимое вкладок исчезало при переключении между ними. Я попытался добавить класс fade
в теги tab
(аналогично тому, как это сделать с файлом bootstrap3 js), но это не сработало.
Большое спасибо!
Ответы
Ответ 1
Так как tabset использует ng-class
для управления вкладкой "active", что позволяет нам определить эффект затухания с анимацией angular, установив opacity = 0, когда "активный" класс удален/присоединен.
Сначала вам нужно загрузить модуль ngAnimate
, включив angular-animate.js
и настроить зависимость.
Добавьте в свой <head>
:
<script src="https://code.angularjs.org/1.2.24/angular-animate.js"></script>
Задайте зависимость модуля:
angular.module("myApp", ["ui.bootstrap", "ngAnimate"]);
Теперь добавьте класс анимации в ваш таблеток.
<tabset class="tab-animation">
<tab heading="Tab1">Some content</tab>
<tab heading="Tab2">Other content</tab>
</tabset>
Поместите следующий код в ваш файл css:
/* set reference point */
.tab-animation > .tab-content {
position: relative;
}
/* set animate effect */
.tab-animation > .tab-content > .tab-pane{
transition: 0.2s linear opacity;
}
/* overwrite display: none and remove from document flow */
.tab-animation > .tab-content > .tab-pane.active-remove {
position: absolute;
top: 0;
width: 100%;
display: block;
}
/* opacity=0 when removing "active" class */
.tab-animation > .tab-content > .tab-pane.active-remove-active {
opacity: 0;
}
/* opacity=0 when adding "active" class */
.tab-animation > .tab-content > .tab-pane.active-add {
opacity: 0;
}
Это все. Вы можете проверить демонстрацию на Plunker.
Также посмотрите документ ngAnimate.
Ответ 2
Я закончил загрузку файла ui-bootstrap.
Я все еще ноб с AngularJS, поэтому, пожалуйста, простите жаргон.
Это нетрадиционный взлом, и его нужно реконфигурировать с помощью ng-animate, но он работает.
Откройте ui-bootstrap-tpls-0.10.0.js и найдите директиву "tab":
.directive('tab', ['$parse', function($parse) {
return {
require: '^tabset',
restrict: 'EA',
replace: true,
templateUrl: 'template/tabs/tab.html',
transclude: true,
scope: {
id:'@', // PATCH : GETTING TAB 'id' ATTRIBUTE
heading: '@',
onSelect: '&select', //This callback is called in contentHeadingTransclude
//once it inserts the tab content into the dom
onDeselect: '&deselect'
},
// ...
Обратите внимание на дополнительный код для получения значения атрибута id (через переход, я думаю).
Несколько строк ниже, найдите:
scope.$watch('active', function(active) {
и скопируйте его так:
scope.$watch('active', function(active) {
// Note this watcher also initializes and assigns scope.active to the
// attrs.active expression.
setActive(scope.$parent, active);
if (active) {
tabsetCtrl.select(scope);
scope.onSelect();
tab_id = attrs.id;
$(".tab_pane_"+tab_id).hide(); // HIDE AT FIRST, SO IT CAN ACTUALLY FADE IN
$(".tab_pane_"+tab_id).fadeIn(1000); // JQUERY TARGETING BY CLASS
} else {
scope.onDeselect();
tab_id = attrs.id;
$(".tab_pane_"+tab_id).hide(); // JQUERY TARGETING BY CLASS
}
});
Несколько строк ниже, найдите:
scope.select = function() {
и добавьте внутрь:
$(".tab-pane").hide();
поэтому все панели вкладок сначала спрятаются должным образом.
Затем найдите:
angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) { ...
и добавьте класс css в элемент tab-panel в соответствующем шаблоне, например:
angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/tabs/tabset.html",
"\n" +
"<div class=\"tabbable\">\n" +
" <ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
" <div class=\"tab-content\">\n" +
" <div class=\"tab-pane tab_pane_{{tab.id}}\" \n" + // CLASS NAME IS DYNAMIC
" ng-repeat=\"tab in tabs\" \n" +
" ng-class=\"{active: tab.active}\"\n" +
" tab-content-transclude=\"tab\">\n" +
" </div>\n" +
" </div>\n" +
"</div>\n" +
"");
}]);
После изменения файла uj-bootstrap.js вы должны отредактировать свой шаблон представления (где вы извлекаете вкладки) и объявить атрибут id:
<!-- TABS -->
<tabset justified="true">
<tab ng-repeat="tab in tabs" heading="{{tab.title}}" id="{{tab.id}}" >
// ... TAB CONTENT
Вы должны получить базовую концепцию, в настоящее время она не очень элегантная (мягко говоря).
Но он работает.
В случае, если вам интересно, как мои вкладки получили идентификаторы, ну, я ввел их в контроллер:
Tab1 = {
id:1,
'ShortDescription': ShortDescription,
'FullDescription': FullDescription,
'TabContent': TabContent1,
title: "ProductTabTitleDefault1",
// active:true
};
Tab2 = {
id:2,
'ShortDescription': ShortDescription,
'FullDescription': FullDescription,
'TabContent': TabContent1,
title: "ProductTabTitleDefault2",
// active:true
};
$rootScope.tabs = {
'Tab1': Tab1,
'Tab2': Tab2,
};
Конечно, это данные макета, но при условии, что ваши вкладки и их содержимое являются динамическими, вы можете использовать счетчик и, возможно, использовать другой ключ вместо "id" (но вам придется соответствующим образом изменить остальные).
Ответ 3
У меня есть альтернативное решение для хорошо написанного решения @user3413125. Он использует @keyframes для достижения перекрестного затухания, а не затухания, за которым следует постепенное исчезновение. См. демо на Plunker
Вот фрагментация CSS (постепенное уменьшение):
.tab-animation > .tab-content > .tab-pane.active-add {
animation: 1s fade-in;
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
Технология ключевого кадра взята из Учебник AngularJs 14 - найдите "Анимация ключевого кадра CSS: анимация ngView", примерно на половину страницы.