CSS Transition 不显示指令 [英] CSS Transition not showing with directive

查看:28
本文介绍了CSS Transition 不显示指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究转换和指令.我创建了一个 Card 指令,当点击它时,它应该以全屏方式显示它自己的克隆.如果我不在超时中应用更改的 css 类,则不会发生转换.应该这样做吗?

<div data-card class='card'>timeout</div><div data-card='notimeout' class='card'>不超时</div>

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

.card {宽度:10vh;高度:14vh;背景颜色:粉红色;边距:10px;}.card.goto.fullscreen {过渡:所有 0.6s 线性;}.card.fullscreen {高度:95vh;宽度:68vh;位置:绝对;位置:绝对;顶部:50%!重要;左:50%!重要;边距:0;变换:平移(-50%,-50%)旋转Y(360度);}

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

var app = angular.module('trans', []);app.directive('card', ['$document', '$timeout', function ($document, $timeout) {返回 {限制:'A',链接:链接,范围: {}};功能链接(范围,元素,属性){var 克隆;element.on('点击', function () {如果(克隆){clone.off().remove();}克隆 = element.clone();var spec = getCardSpecifications();克隆.css({'边距':'0','top': 规格顶部 + 'px','left': spec.left + 'px','位置':'绝对'});$document.find('body').append(clone);clone.addClass('goto');如果(attrs.card == 'notimeout'){clone.addClass('全屏');} 别的 {$超时(函数(){clone.addClass('全屏');}, 0);}});函数 getCardSpecifications() {var 规格 = {};spec.top = element.prop('offsetTop');spec.left = element.prop('offsetLeft');spec.height = element[0].offsetHeight;spec.width = element[0].offsetWidth;返回规格;}}}]);

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

解决方案

这个问题与 Angular 本身没有任何关系,而是与创建一个新的 DOM 节点并在之后立即在其上设置一个类有关.例如,描述了这样的问题.这里,它使用与第一个示例中相同的解决方案.

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

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

clone.ready(function() {clone.addClass('全屏');});

这与使用 0ms 超时几乎相同,但 a. 更具描述性并且 b. 适用于所有情况,而超时解决方案有时显然在 Firefox 中失败(参见 linked文章).

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

<小时>

为什么会发生这种情况,即使您在追加后"添加类,我也无法快速找出.或许 append 最有可能使用 internall 的 appendChild 是异步的(即将 DOM 操作任务推送到事件队列)?如果您真的对这个问题的原因感兴趣,那么更多的谷歌搜索可能会很有用.

I'm playing with transitions and directives. I've created a Card directive that should show a clone of it self in fullscreen when clicked. The transition doesn't happen if I don't apply the altering css class in a timeout. Is that how it should be done?

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

Between to original position and the fullscreen mode it should transition with a spin. The goto class is just so that i can add/remove transitions so that the card doesn't transition widht/height when the window is resized. I think it reads nice too =)

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

This is a simplified version of my directive.

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

    }
}]);

I've created this jsfiddle that demonstrates the problem.

解决方案

The problem doesn't have anything to do with Angular itself, but with creating a new DOM node and setting a class on it right after. Such a problem is described e.g. here, and it uses the same solution as yours in the first example.

DISCLAIMER: The real Angular way of doing this would be ngAnimate. What follows is a solution that is almost the same as the OP's, and one you'd only want to use if you don't want to depend on that module – but it's only ~11kb uncompressed, and 4kb gzipped. Choose wisely!

What also worked for me is waiting for the DOM node to be ready:

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

This amounts to almost the same thing as using a 0ms timeout, but is a. more descriptive and b. works in all cases, while the timeout solution apparently sometimes fails in Firefox (see linked article).

The second solution given in the article also reads a little more hackish (matter of opinion, really), and you'll have to retrieve the actual DOM element instead of the jqLite wrapper around it to use it.


Why exactly this happens, even though you are adding the class "after appending", I wasn't able to quickly find out. Perhaps appendChild, which append most likely uses internall, is asynchronous (i.e. pushes the DOM manipulation task onto the event queue)? Some more googling might be useful if you're really interested in the cause of this problem.

这篇关于CSS Transition 不显示指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆