因此,我使用此指令折叠Ionic中的可变高度卡。该指令获取自动高度并将其更改为定义的高度,然后可以使用css动画将其折叠为0。它可以满足我的需求,但现在我需要使用ng-src
动态加载卡片中的图像。发生的是在指令后正在加载图像,因此图像会加载并溢出卡片。
指令:
.directive('collapse', ['$timeout', function ($timeout) {
return {
restrict: 'A',
link: function ($scope, ngElement, attributes) {
var element = ngElement[0];
$timeout(function(){
$scope.$watch(attributes.collapse, function (collapse) {
var newHeight = collapse ? 0 : getElementAutoHeight();
element.style.height = newHeight +"px";
ngElement.toggleClass('collapsed', collapse);
});
function getElementAutoHeight() {
var currentHeight = getElementCurrentHeight();
element.style.height = 'auto';
var autoHeight = getElementCurrentHeight();
element.style.height = currentHeight +"px";
getElementCurrentHeight(); // Force the browser to recalc height after moving it back to normal
return autoHeight;
}
function getElementCurrentHeight() {
return element.offsetHeight
}
});
}
};
}])
和HTML:
<div ng-repeat="item in items | orderBy : '-'" collapse="item.deleted">
<div class="list card">
<img class="full-image" ng-src="{{item.image}}"/>
</div>
</div>
正如你所看到的那样,我注入$timeout
并将间隔留空,希望它会等到DOM加载,但似乎无论我如何使用它,该指令仍明确设置渲染image子元素之前css中元素的高度。如何在每个ng-src
项目中加载ng-repeat
之前延迟元素高度的设置?
答案 0 :(得分:1)
首先,没有$ interval的angular $ timeout 不会等待DOM树加载,基本上,它所做的是等待当前摘要周期到在第一个参数中执行函数之前完成。通过这样做,它将允许您的代码在计算div的高度之前等到指令完成编译和渲染。
但是,无法保证此时将加载图像。浏览器独立于DOM渲染加载图像,因此,要精确计算具有图像的容器的高度,您应该使用 JS Image Object 和加载事件 。图像完全加载后,您可以更新高度。
另外,对于你的指令,我不认为你需要每次折叠变量改变时计算高度(在手表内),你可以等到图像被加载,计算高度一次,存储它位于范围对象内部,并在崩溃变量发生变化时重复使用它。
答案 1 :(得分:0)
好的,感谢泰国人的投入,我有一个有效的解决方案:
.directive('collapse', [function () {
return {
restrict: 'A',
link: function ($scope, ngElement, attributes) {
var element = ngElement[0];
var img = element.querySelector('.full-image');
angular.element(img).bind('load', function() {
var autoHeight = getElementAutoHeight();
element.style.height = autoHeight + "px";
});
$scope.$watch(attributes.collapse, function (collapse) {
var newHeight = collapse ? 0 : getElementAutoHeight();
element.style.height = newHeight +"px";
ngElement.toggleClass('collapsed', collapse);
});
function getElementAutoHeight() {
var currentHeight = getElementCurrentHeight();
element.style.height = 'auto';
var autoHeight = getElementCurrentHeight();
element.style.height = currentHeight +"px";
getElementCurrentHeight(); // Force the browser to recalc height after moving it back to normal
return autoHeight;
}
function getElementCurrentHeight() {
return element.offsetHeight
}
}
};
}])