javascript AngularJS - 如何在指令渲染完成时查询 DOM
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14235669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS - How to query the DOM when directive rendering is complete
提问by Shlomi Schwartz
I'm trying to implement a custom scroll pane component using an AngularJS directive. in the following jsfiddle exampleI have an example of the basic prototype.
我正在尝试使用 AngularJS 指令实现自定义滚动窗格组件。在下面的jsfiddle 示例中,我有一个基本原型的示例。
here is a schema of my idea:
这是我的想法的架构:
Here is the directive code:
这是指令代码:
myApp.directive('lpScrollPane', function factory() {
return {
restrict: 'A',
replace: true,
transclude: true,
template: '<div class="scrollPaneWrapper"><div class="scrollPane" ng-transclude></div><div class="thumbTrack" ></div></div>',
compile: function (tElement, tAttrs) {
var minHeight = 30;
return function (scope, iElement, iAttrs) {
var thumbTrack = angular.element(iElement.children()[1]);
scope.onScrollHeight = function () {
console.log(iElement.children()[0].scrollHeight);
var H1 = iElement[0].offsetHeight;
var H2 = iElement.children()[0].scrollHeight;
if (H2 > H1) {
var trackHeight = Math.round(minHeight + (H1 - minHeight) * (1 - Math.pow((H2 - H1) / H2, 0.8)));
thumbTrack.css({
display: "block",
height: trackHeight + "px"
});
console.log(H2, H1, trackHeight);
} else {
thumbTrack.css({
display: "none"
});
}
};
scope.$watch(function () {
scope.onScrollHeight();
//setTimeout(scope.onScrollHeight, 100)
});
}
}
};
});
Basically there are 2 dives 1 with overflow hidden and one with overflow scroll and another div to mimic the thumb tracker.
基本上有 2 次潜水,1 次隐藏溢出,一次溢出滚动,另一个 div 模仿拇指跟踪器。
My Goal is to monitor the scrollHeight property and then change the tracker height accordingly. the issue is the $watch gets fired before the DOM is rendered so there is a delay in showing and calculating the tracker. For now I used setTimeout on the watch function and it works fine (un-comment line 35 and comment 34 to see it in action).
我的目标是监视 scrollHeight 属性,然后相应地更改跟踪器高度。问题是 $watch 在渲染 DOM 之前被触发,因此显示和计算跟踪器有延迟。现在我在 watch 函数上使用了 setTimeout 并且它工作正常(取消注释第 35 行和注释 34 以查看它的运行情况)。
What would be the right way to do it?
什么是正确的方法呢?
回答by Mark Rajcok
See is there a post render callback for Angular JS directive?
Unfortunately, there is no way to determine when rendering is complete (e.g., there is no event). Using $timeout seems to be the best workaround available.
不幸的是,无法确定渲染何时完成(例如,没有事件)。使用 $timeout 似乎是可用的最佳解决方法。
In the link above, @Nik mentioned in a comment that he was checking $('tr').length > 3
, for his particular scenario, to determine when rendering was complete. Maybe there is something you could periodically examine in the DOM to determine that rendering is complete.
在上面的链接中,@Nik 在评论中提到他正在检查$('tr').length > 3
他的特定场景,以确定渲染何时完成。也许您可以定期检查 DOM 中的某些内容以确定渲染已完成。
回答by asgoth
Two observations:
两个观察:
- you don't need
compile
imho, butlink
function - you should wait until the element is ready, instead of using timeout
- 你不需要
compile
恕我直言,但link
功能 - 你应该等到元素准备好,而不是使用超时
So:
所以:
myApp.directive('lpScrollPane', function factory() {
return {
restrict: 'A',
replace: true,
transclude: true,
template: '<div class="scrollPaneWrapper"><div class="scrollPane" ng-transclude></div><div class="thumbTrack" ></div></div>',
link: function (scope, iElement, iAttrs) {
var minHeight = 30;
var thumbTrack = angular.element(iElement.children()[1]);
scope.onScrollHeight = function () {
console.log(iElement.children()[0].scrollHeight);
var H1 = iElement[0].offsetHeight;
var H2 = iElement.children()[0].scrollHeight;
if (H2 > H1) {
var trackHeight = Math.round(minHeight + (H1 - minHeight) * (1 - Math.pow((H2 - H1) / H2, 0.8)));
thumbTrack.css({
display: "block",
height: trackHeight + "px"
});
console.log(H2, H1, trackHeight);
} else {
thumbTrack.css({
display: "none"
});
}
};
iElement.ready(function () {
scope.$watch(function () {
scope.onScrollHeight();
});
});
}
};
});
See jsFiddle.
参见jsFiddle。
Edit:
编辑:
Because 2 images say more than 1000 words, here are two screenshots:
因为2张图片说1000多个字,这里有两张截图: