Javascript 如何根据其他元素的高度设置页脚的边距(角度和无jQuery)?
正如我在问题中所说的,我试图实现的是类似以下代码的等效代码: jQuery方式Javascript 如何根据其他元素的高度设置页脚的边距(角度和无jQuery)?,javascript,jquery,html,angularjs,Javascript,Jquery,Html,Angularjs,正如我在问题中所说的,我试图实现的是类似以下代码的等效代码: jQuery方式 $(document).ready(function(){ var windowHeight = $(window).height(); var headerHeight = $('header').height(); var footerHeight = $('footer').height(); var contentHeight = $('.content').height(); var p
$(document).ready(function(){
var windowHeight = $(window).height();
var headerHeight = $('header').height();
var footerHeight = $('footer').height();
var contentHeight = $('.content').height();
var paginationHeight = $('.pagination').height();
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
$('footer').on('content.loaded', function() {
if(footerMarginTop > 0) {
$(this).css('margin-top', footerMarginTop + 'px');
}
}
});
angular.module('myApp', []).directive('FooterMargin', ['$window', '$document', function($window, $document){
return {
restrict: 'A',
link: function(scope, element, attrs) {
var windowHeight = $window.innerHeight;
var headerHeight = $document[0].getElementById('header').offsetHeight;
var footerHeight = $document[0].getElementById('footer').offsetHeight;
var paginationHeight = $document[0].getElementById('pagination').offsetHeight;
var contentHeight = $document[0].getElementById('content').offsetHeight;
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
scope.$on('content.loaded', function(){
if(footerMarginTop > 0) {
attrs.$set('style', 'margin-top: ' + footerMarginTop + 'px');
}
}
});
}
};
}]);
在文档准备就绪时,我必须在加载页面内容后,根据其他元素的高度计算设置页脚顶部的边距。
在jQuery中思考很容易,但在Angular中,我没有找到其他方法,除了像这样直接翻译它,使用目录
角度方式
$(document).ready(function(){
var windowHeight = $(window).height();
var headerHeight = $('header').height();
var footerHeight = $('footer').height();
var contentHeight = $('.content').height();
var paginationHeight = $('.pagination').height();
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
$('footer').on('content.loaded', function() {
if(footerMarginTop > 0) {
$(this).css('margin-top', footerMarginTop + 'px');
}
}
});
angular.module('myApp', []).directive('FooterMargin', ['$window', '$document', function($window, $document){
return {
restrict: 'A',
link: function(scope, element, attrs) {
var windowHeight = $window.innerHeight;
var headerHeight = $document[0].getElementById('header').offsetHeight;
var footerHeight = $document[0].getElementById('footer').offsetHeight;
var paginationHeight = $document[0].getElementById('pagination').offsetHeight;
var contentHeight = $document[0].getElementById('content').offsetHeight;
var footerMarginTop = (windowHeight - headerHeight - footerHeight) - (contentHeight + paginationHeight);
scope.$on('content.loaded', function(){
if(footerMarginTop > 0) {
attrs.$set('style', 'margin-top: ' + footerMarginTop + 'px');
}
}
});
}
};
}]);
我已经在元素中添加了ID,以从角度检索它们,但即使它起作用,在我看来这并不是一个好方法,而且很难对其进行单元测试
我不能在这个项目中使用jQuery,我已经使用Angular for其他指令来处理更容易获得的事件(比如modals和dropdown),并取得了令人满意的效果
你能帮我理解如何以更好的角度处理这个问题吗?试试这个
angular
.module('myApp')
.directive('FooterMargin', [
function() {
function calculateMargins() {
// elements
var $windowHeight = angular.element(window).height(),
$headerHeight = angular.element('#header').height(),
$footerHeight = angular.element('#footer').height(),
$paginationHeight = angular.element('#pagination').height(),
$contentHeight = angular.element('#content').height();
// margin
return ($windowHeight - $headerHeight - $footerHeight) - ($contentHeight + $paginationHeight);
};
return {
restrict: 'A',
link: function($scope, element, attrs) {
// optional (window resize)
angular.element(window).off("resize").on("resize", function(){
// will trigger event to get new margin
$scope.$broadcast('content.loaded');
});
// some event
$scope.$on('content.loaded', function() {
var marginTop = calculateMargins();
if (marginTop > 0) {
element.css('margin-top', marginTop);
}
});
}
};
}
]);
注意“angular.element”的用法。这是一种代理方法,用作jQLite和jQuery的抽象
我还添加了一个窗口大小调整事件。这是可选的,但是如果窗口大小改变,页脚将重新计算
最后,
其中大部分可以通过CSS实现。我怀疑你做不到。在DOM中查询5个元素的开销很大。也就是说,运用你的判断力
在“链接”方法之外定义方法也是一种很好的做法。从理论上讲,这减少了在编译和“消化”指令时浏览器的内存分配。一种更具角度的方法是使用服务和另一个指令,该指令定义要选择的元素并将其高度设置为服务 然后,原始指令将从新服务检索预先计算的高度 在我的示例中,我将工厂
heightFactory
用作服务。我还必须添加一个难看的超时,以等待DOM元素正确呈现(并具有一个大小)。我认为这就是您希望在示例中使用scope.$on('content.loaded')
实现的目标
请注意标记中的指令用法,例如,对于具有页眉高度的元素,set height=“header”
。
每个元素向服务注册其高度后,heightFactory.getMarginTop()
的返回值将根据您的算法
//此指令将存储窗口高度并从高度服务中检索边距值
angular.module('myApp',[])指令('footerMargin',['$window','heightFactory',
功能($window,heightFactory){
返回{
限制:“A”,
链接:函数(范围、元素、属性){
heightFactory.setHeight('window',$window.innerHeight);
//仅出于测试目的而延迟,请删除此选项
$window.setTimeout(函数(){
属性$set('style','margin top:'+heightFactory.getMarginTop()+'px');
log(heightFactory.getMarginTop());
}, 1000);
作用域:$on('content.loaded',function(){
如果(heightFactory.getMarginTop()>0){
属性$set('style','margin top:'+heightFactory.getMarginTop()+'px');
}
});
}
};
}
]);
//此指令用于计算所需的每个元素的大小
角度.module('myApp')。指令('setHeight',['heightFactory',',
功能(高度工厂){
返回{
限制:“A”,
链接:函数(范围、元素、属性){
元素。就绪(函数(){
heightFactory.setHeight(attrs['setHeight'],元素[0]。offsetHeight);
log(attrs['setHeight']+'设置为'+元素[0]。offsetHeight);
});
}
}
}
]);
//边距的算法是硬编码的,这个服务也可以只返回一个具有高度的对象,并且算法仍然在您的原始指令中。这取决于用例imho。
角度。模块('myApp')。工厂('heightFactory'[
函数(){
变量高度={};
返回{
设置高度:函数(元素、值){
高度[元素]=值;
},
getMarginTop:function(){
返回(高度['window']-高度['header']-高度['footer'])-(高度['content']+高度['pagination']);
}
};
}
]);代码>
#标题{
背景色:红色;
}
#页脚{
背景颜色:蓝色;
}
#分页{
背景颜色:灰色;
}
标题
一些内容
一些内容
一些内容
一些内容
某些元素
1 2 3 4 5 6
页脚
为什么要用javascript而不是CSS来做这件事?另外,您可以使用angular中包含的Jquery lite。我不能只使用css,因为我必须将页脚推到底,让用户能够看到折叠上方页面的最终内容,所以我必须根据内容高度计算所有内容(这总是不同的)。我不使用jqLite,因为它不可能用类或IDS选择标记。你也可以用普通Javascript来做。我知道用普通JS做这件事是可能的,但我的问题是要找到一个角度更高的解决方案,因为我不清楚如何做。如果没有解决方案,我会坚持我在问题中提出的解决方案,那就是效果很好。你能解释更多的“大部分可以通过CSS实现”吗?