javascript - 我如何根据其他元素的高度设置页脚的边距,在 Angular 中而不是 jQuery?

标签 javascript jquery html angularjs

正如我在问题中所说,我想要实现的是仅在 Angular 中实现的等价代码:

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');
    }
  }
});

在文档准备好后,我必须在页面内容加载后根据其他元素的高度计算来设置页脚的顶部边距。 在 jQuery 中思考很容易做到,但在 Angular 中我没有找到其他方法,除了像这样直接翻译它,用一个目录

Angular 方式

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 添加到我的元素以在 Angular 中检索它们,但即使它有效,在我看来这也不是一个好方法,而且也很难对其进行单元测试。

我不能在这个项目中使用 jQuery,我已经将 Angular 用于其他更容易以令人满意的方式获得的事件指令(如模式和下拉列表)

你能帮我理解如何以更好的 Angular 方式处理这个问题吗?

最佳答案

更 Angular 的方法可能是使用 服务 和另一个指令,它定义了您要选择的元素并将它们的高度设置为服务。

然后您的原始指令将从新服务中检索预先计算的高度。

在我的示例中,我使用工厂 heightFactory 作为服务。我还必须添加一个丑陋的超时来等待正确呈现 DOM 元素(并具有大小)。我认为这也是您希望在您的示例中使用 scope.$on('content.loaded') 实现的。

请注意标记中指令的用法,例如 set-height="header",对于具有标题高度的元素。 在每个元素向服务注册它们的高度后,heightFactory.getMarginTop() 的返回值将根据您的算法。

// this directive will ste the window height and retrieve the margin value from the height service
angular.module('myApp', []).directive('footerMargin', ['$window', 'heightFactory',
  function($window, heightFactory) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {

        heightFactory.setHeight('window', $window.innerHeight);

        // delay only for testing purposes, remove this
        $window.setTimeout(function() {
          attrs.$set('style', 'margin-top: ' + heightFactory.getMarginTop() + 'px');
          console.log(heightFactory.getMarginTop());
        }, 1000);


        scope.$on('content.loaded', function() {
          if (heightFactory.getMarginTop() > 0) {
            attrs.$set('style', 'margin-top: ' + heightFactory.getMarginTop() + 'px');
          }
        });
      }
    };
  }
]);

// this directive is used for each element, whichs size you want need for your calculation
angular.module('myApp').directive('setHeight', ['heightFactory',
  function(heightFactory) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.ready(function() {
          heightFactory.setHeight(attrs['setHeight'], element[0].offsetHeight);
          console.log(attrs['setHeight'] + ' set to ' + element[0].offsetHeight);
        });
      }
    }

  }
]);

// the algorithm for the margin is hardcoded, this service could also just return an object with the heights, and the algorithm would still be in your original directive. It depends on the use case imho.
angular.module('myApp').factory('heightFactory', [
  function() {
    var height = {};

    return {
      setHeight: function(element, value) {
        height[element] = value;
      },
      getMarginTop: function() {
        return (height['window'] - height['header'] - height['footer']) - (height['content'] + height['pagination']);
      }
    };

  }
]);
#header {
  background-color: red;
}
#footer {
  background-color: blue;
}
#pagination {
  background-color: grey;
}
<body ng-app="myApp">
  <header id="header" set-height="header">Header</header>

  <section id="content" set-height="content">
    <p>Some Content</p>
    <p>Some Content</p>
    <p>Some Content</p>
    <p>Some Content</p>
  </section>

  <div id="some element" footer-margin>Some Element</div>
  <section id="pagination" set-height="pagination">
    1 2 3 4 5 6
  </section>
  <footer id="footer" set-height="footer">Footer</footer>

</body>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

关于javascript - 我如何根据其他元素的高度设置页脚的边距,在 Angular 中而不是 jQuery?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29749070/

相关文章:

javascript - 用于克隆单选按钮的 jQuery .show() 和 .hide()

javascript - 表单验证(包括输入文件)的问题

javascript - 单击后检索元素/文本

javascript - PhP错误;尝试打印到控制台

javascript - 使用 javascript/jquery 检查 .css 样式表的名称

javascript - 选中时未触发复选框单击事件

HTML5 拖拽复制?

html - CSS:始终将页脚放在底部

html - 是否有类似 Trello 的开源 html 菜单组件?

javascript - ID 中具有跳过序列的动态控件