【问题标题】:CSS Transition not showing with directiveCSS 过渡未与指令一起显示
【发布时间】:2014-12-21 21:41:57
【问题描述】:

我在玩转场和指令。我创建了一个 Card 指令,单击该指令时应在全屏中显示它的克隆。如果我在超时时不应用更改的 css 类,则不会发生转换。应该这样吗?

<div ng-app='trans'>
    <div data-card class='card'>timeout</div>
    <div data-card='notimeout' class='card'>not timeout</div>
</div>

在原始位置和全屏模式之间,它应该旋转过渡。 goto 类只是为了让我可以添加/删除转换,以便在调整窗口大小时卡片不会转换宽度/高度。我也觉得很好看=)

.card {
    width:10vh;
    height:14vh;
    background-color:pink;
    margin: 10px;
}
.card.goto.fullscreen {
    transition: all 0.6s linear;
}
.card.fullscreen {
    height:95vh;
    width: 68vh;
    position:absolut;
    position: absolute;
    top: 50% !important;
    left: 50% !important;
    margin: 0;
    transform: translate(-50%, -50%) rotateY(360deg);
}

这是我的指令的简化版本。

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

app.directive('card', ['$document', '$timeout', function ($document, $timeout) {
    return {
        restrict: 'A',
        link: link,
        scope: {}
    };

    function link(scope, element, attrs) {

        var clone;
        element.on('click', function () {

            if (clone) {
                clone.off().remove();
            }

            clone = element.clone();
            var spec = getCardSpecifications();

            clone.css({
                'margin': '0',
                    'top': spec.top + 'px',
                    'left': spec.left + 'px',
                    'position': 'absolute'
            });
            $document.find('body').append(clone);

            clone.addClass('goto');

            if (attrs.card == 'notimeout') {

                clone.addClass('fullscreen');
            } else {

                $timeout(function () {
                    clone.addClass('fullscreen');
                }, 0);
            }

        });

        function getCardSpecifications() {
            var spec = {};
            spec.top = element.prop('offsetTop');
            spec.left = element.prop('offsetLeft');
            spec.height = element[0].offsetHeight;
            spec.width = element[0].offsetWidth;
            return spec;
        }

    }
}]);

我创建了这个 jsfiddle 来演示问题。

【问题讨论】:

    标签: angularjs angularjs-directive css-transitions


    【解决方案1】:

    问题与 Angular 本身无关,而是与创建一个新的 DOM 节点并在其上设置一个类有关。这样的问题被描述为例如here,它使用的解决方案与您在第一个示例中的解决方案相同。

    免责声明:真正的 Angular 方法是 ngAnimate。接下来是一个与 OP 几乎相同的解决方案,如果您不想依赖该模块,您只想使用该解决方案 - 但它只有 ~11kb 未压缩和 4kb gzipped。明智地选择!

    对我有用的是等待 DOM 节点准备好:

    clone.ready(function() {
        clone.addClass('fullscreen');
    });
    

    这与使用 0 毫秒超时几乎相同,但 a. 更具描述性,b. 适用于所有情况,而超时解决方案显然有时在 Firefox 中失败(请参阅 linked article)。

    文章中给出的第二个解决方案读起来也有点骇人听闻(实际上是意见问题),您必须检索实际的 DOM 元素而不是围绕它的 jqLit​​e 包装器才能使用它。


    为什么会发生这种情况,即使您在“附加后”添加类,我也无法快速找出。或许appendChild(其中append 最有可能在内部使用)是异步的(即将DOM 操作任务推入事件队列)?如果您真的对导致此问题的原因感兴趣,则进行更多谷歌搜索可能会很有用。

    【讨论】:

    • 对不起,那是我,这只是误导,“准备好”可能会解决问题,但这只是由于超时的原因相同,并且 ngAnimate 是专门为解决此类问题而创建的。
    • 在这个简单的用例中 element.ready 会不会更好,因为我不依赖 $animate? $animate 需要在内部做类似的事情,对吧?现在我不需要整个 $animate 包。但是如果东西变得更高级,我会记得使用 $animate 。我还将阅读 $animate。
    • 这实际上是真的@Dylan,我为 ngAnimate 添加了免责声明。
    • 我想如果它能让你通过,我只是看不出它和 $timeout 有什么不同。 ngAnimate 还允许您执行反向操作,而 16k 依赖项并不是不使用某些东西的好理由。
    • 这是一种更具描述性的方式(等待 DOM 节点准备好,而不是仅仅推入队列),并且显然使用超时有时无法在 Firefox 中工作(请参阅我的链接文章)。我还附上了关于图书馆大小的注释。
    【解决方案2】:

    你可能应该使用 animate 来制作动画

     $animate.addClass(clone, 'fullscreen'
    

    我在尝试获取 animate 的依赖项时遇到了问题,所以

    我发了Plunker

    【讨论】:

    • 感谢它有效,但我更喜欢 element.ready。不依赖 $animate。
    【解决方案3】:

    当使用诸如 css 之类的方法通过指令更改 DOM 时,您必须通知摘要循环这些更改。

    为了实现这一点,您应该在 if 语句中添加 css 类之后添加 scope.$apply()。 $timeout 为您工作的原因是因为它在超时执行后调用 $apply 。

    【讨论】:

    • 我将它添加到new fiddle。似乎不起作用。有什么想法吗?
    • 是的,刚刚看到并没有解决这个问题。我建议您看一下使用 $animate 进行转换的 Angular 方式:docs.angularjs.org/api/ngAnimate/service/$animate
    • 谢谢。我将阅读 $animate。但是我喜欢 element.ready 的答案,这种情况是不需要更高级的。所以我不依赖 $animate
    • 你说的没错,但是用 CSS 动画类与 Angular 无关。 Angularjs 不需要被“告知”。
    • 是的,很抱歉造成混乱。
    猜你喜欢
    • 2018-01-16
    • 2014-04-26
    • 1970-01-01
    • 2020-03-27
    • 2015-07-11
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多