Javascript 如何根据其他元素的高度设置页脚的边距(角度和无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

正如我在问题中所说的,我试图实现的是类似以下代码的等效代码:

jQuery方式

$(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实现”吗?