我正在玩转换和指令。我已经创建了一个Card指令,它应该在单击时全屏显示它的自我克隆。如果我不在超时中应用更改css类,则不会发生转换。是应该怎么做?
<div ng-app='trans'>
<div data-card class='card'>timeout</div>
<div data-card='notimeout' class='card'>not timeout</div>
</div>
在原始位置和全屏模式之间,它应该旋转过渡。 goto类只是为了我可以添加/删除转换,以便在调整窗口大小时卡不会转换为widht / height。我觉得它也很好看=)
.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来证明问题。
答案 0 :(得分:1)
问题与Angular本身没有任何关系,但是创建一个新的DOM节点并在其后设置一个类。例如描述了这样的问题。 here,它在第一个示例中使用与您相同的解决方案。
免责声明:真正的Angular方式是ngAnimate。以下是一个几乎与OP相同的解决方案,如果您不想依赖该模块,那么您只想使用该解决方案 - 但它只是~11kb未压缩,4kb压缩。明智地选择!
对我来说也有用的是等待DOM节点准备就绪:
clone.ready(function() {
clone.addClass('fullscreen');
});
这几乎与使用0ms超时几乎相同,但是 a。更具描述性,而 b。在所有情况下都有效,而有时超时解决方案在Firefox中失败(请参阅linked article)。
本文中给出的第二个解决方案也看起来更加hackish(意见问题,真的),并且您必须检索实际的DOM元素而不是围绕它的jqLite包装来使用它。
为什么会发生这种情况,即使你正在添加课程&#34;在追加&#34;之后,我也无法快速找到答案。也许appendChild
append
最有可能使用internall,是异步的(即将DOM操作任务推送到事件队列中)?如果你真的对这个问题的原因感兴趣,那么更多谷歌搜索可能会有用。
答案 1 :(得分:1)
答案 2 :(得分:-1)
使用css等方法通过指令更改DOM时,必须通知摘要循环这些更改。
为了实现这一点,您应该在if语句中添加css类后添加范围。$ apply()。 $ timeout对你有用的原因是因为它在执行超时后调用$ apply。