【问题标题】:Fade effect for tabs in ui-bootstrap (Angular.JS)ui-bootstrap(Angular.JS)中选项卡的淡入淡出效果
【发布时间】:2013-10-21 19:43:43
【问题描述】:

如何使用 angular-ui-bootstrap 向标签集添加淡入淡出动画?

例如,给定以下代码:

<tabset>
    <tab heading="Tab1">Some content</tab>
    <tab heading="Tab2">Other content</tab>
</tabset>

我希望标签的内容在它们之间切换时淡出。我尝试将fade 类添加到tab 标记中(类似于使用 bootstrap3 js 文件的方式),但没有成功。

非常感谢!

【问题讨论】:

  • 尝试阅读 $animate 的文档 - 也许它会给你一些想法。
  • 我会...我希望有一些我忽略的快速解决方案,因为使用 bootstrap3 js 很容易做到

标签: javascript angularjs twitter-bootstrap-3 angular-ui-bootstrap


【解决方案1】:

由于 tabset 使用ng-class 来控制“活动”选项卡,这允许我们通过在“活动”类被移除/附加时设置 opacity=0 来定义带有角度动画的淡入淡出效果。

首先,您需要通过包含angular-animate.js 来加载ngAnimate 模块并设置依赖关系。

添加到您的&lt;head&gt;

<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;
}

就是这样。您可以查看demo on Plunker

也可以看看ngAnimate doc

【讨论】:

    【解决方案2】:

    我最终修补了 ui-bootstrap 文件。 我仍然是 AngularJS 的菜鸟,所以请原谅行话。 这是一个非常规的 hack,需要使用 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's 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-pane元素中,如下所示:

    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" +
    "");
    }]);
    





    修改 ui-bootstrap .js 文件后,您必须编辑视图模板(获取选项卡的位置)并声明 'id' 属性:

        <!-- TABS -->
        <tabset justified="true">
            <tab ng-repeat="tab in tabs" heading="{{tab.title}}" id="{{tab.id}}" >
                // ... TAB CONTENT
    



    您应该了解基本概念,目前它不是很优雅(委婉地说)。 但它有效。


    如果您想知道我的标签是如何获得 id 的,那么我将它们注入到我的控制器中:

                            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”(但您必须相应地更改其余部分)。

    【讨论】:

    • 将 jQuery 混合到 Angular 项目中并不是最好的方法。
    【解决方案3】:

    对于@user3413125 上面写得很好的解决方案,我有一个替代解决方案。它使用@keyframes 来实现交叉淡入淡出,而不是先淡出再淡入。见demo on Plunker

    这是 CSS 的淡入部分(淡出类似):

    .tab-animation > .tab-content > .tab-pane.active-add {
        animation: 1s fade-in;
    }
    
    @keyframes fade-in {
      from { opacity: 0; }
      to   { opacity: 1; }
    }
    

    关键帧技术取自 AngularJs tutorial 14 - 在页面的大约一半处查找“CSS Keyframe Animations: Animating ngView”。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 2012-06-06
      • 1970-01-01
      • 2023-03-11
      • 2011-03-05
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      相关资源
      最近更新 更多