【问题标题】:When do we know the actual width of an element in Angular?我们什么时候知道 Angular 中元素的实际宽度?
【发布时间】:2013-07-17 13:43:24
【问题描述】:

我正在尝试创建一个将 div 居中的指令。

到目前为止,我有这个代码:

app.directive("setcenter", function () {
    return {
        scope:{
            setcenter: '='
        },
        link: function (scope, element, attrs) {

            scope.$watch('setcenter', function (newValue) {
                if (newValue == true) {
                    var width = element.width();
                    element.css('position', 'absolute');
                    element.css('top', '80px');
                    element.css('left', '50%');
                    element.css('z-index', '200');
                    element.css('margin-left', '-' + width / 2 + 'px');
                }
            });
        }
    }
});

问题是元素的宽度。该指令的重点是使用该指令的 div 没有设置宽度。我希望这个指令能够计算出宽度并将 div 居中。

我遇到的问题是,当指令被调用时,div的实际宽度还不知道。当我在我的情况下使用它时,div 是 800px,但是当页面完成加载时,div 是 221px。

那么,要等到知道 div 的实际宽度,我该怎么办?

【问题讨论】:

  • 问题的标题不应该是关于宽度而不是高度吗?关于你的问题,也许你可以简单地在你的链接函数中添加一个 dom 加载事件监听器并在那里调用你的居中函数。
  • 我尝试将$(document).ready(...) 放入if(newValue == true) 语句中,但没有成功。
  • 我认为问题在于,当 div 具有最终大小时,您现在永远无法真正做到,因为 div 可能包含改变其的绑定(ng-style、ng-bind 等)动态大小。如果您不太担心性能,我认为您可以在 rootscope 上设置一个 $watch 并每次调用您的 centering 方法。
  • 我建议只使用 CSS。听起来您正试图使一个非常简单的设计要求过于复杂化。创建一个 CSS 类并将其附加到您的元素,该 CSS 类将自动将 DIV 居中在您想要的任何父容器中,而不管宽度如何。它甚至可以响应用户调整浏览器大小、更改字体大小等。 stackoverflow.com/questions/114543/…
  • 您是否尝试过使用 element.clientWidth 而不是 element.width?

标签: angularjs angularjs-directive


【解决方案1】:

首先,当我为 directive 而不是 link 函数定义 controller 时,我只使用了这个逻辑。所以在链接函数中定义它可能会导致不同的行为,但我建议你先在那里尝试,如果你不能让它工作,然后切换到使用控制器。

据我所知,您需要进行的唯一更改是将 $scope 更改为范围调用并将 $element 更改为元素,因为依赖注入的对象成为标准链接函数参数。

  $scope.getElementDimensions = function () {
    return { 'h': $element.height(), 'w': $element.width() };
  };

  $scope.$watch($scope.getElementDimensions, function (newValue, oldValue) {
    //<<perform your logic here using newValue.w and set your variables on the scope>>
  }, true);

  $element.bind('resize', function () {
    $scope.$apply();
  });

在阅读了一个非常相似的关于观察 $window 而不是当前元素的用法后,我想到了这个用法,原始作品可以在这里找到。

Angular.js: set element height on page load

【讨论】:

  • 对于那些剪切和粘贴这个例子的人来说,不要忘记 $watch 的第三个参数是“true”——进行深度比较。见groups.google.com/forum/#!topic/angular/slJ7Xj3SYOk
  • 不适用于当前 1.3.16 版本的 AngularJS。由于某些原因,它最初会在适当的值中抛出负宽度 + 高度,这通常在初始更新时会破坏事情。我不知道这是一个错误还是发生了什么变化,但我不得不在手表内使用以下解决方法:if(newValue.w > 0 && newValue.h > 0) {then do the update}跨度>
  • 必须将行为更改为更新的 Angular 版本。我使用了多个版本,包括 angular 1.2.X。感谢您提供的信息,当我将依赖此解决方案的项目更新为更新版本的 angular 时,我会记住这种行为变化。
  • 您是否使用任何样式设置让指令占据整个屏幕 (width:100%)?如果没有,我认为这些维度值永远不会真正改变。
  • $element.height()$element.width() 不是函数。
【解决方案2】:

詹姆斯的回答让我:

app.directive('measureInto', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function() {
                    return element[0].clientWidth;
                }, function(value){
                    scope[attrs.measureInto] = element[0].clientWidth + 10;
                });
            }
        };
    });

所以,在运行时,我添加它并分配到我想要的任何范围变量中我正在寻找的元素的宽度

【讨论】:

【解决方案3】:

我遇到了类似的问题,并发现当页面上的所有 ng-ifs(或使用 ngAnimate 的任何其他内容)都已解决时,尺寸确实正确 - 这里可能会发生类似的事情。如果是这样,这将在不添加任何新侦听器的情况下解决问题:

$scope.tryGetElementDimensions = function () {
    if (!angular.element("your-element") || ((angular.element("your-element")[0].classList).contains("ng-animate")
       $timeout(function() {
           $scope.tryGetElementDimensions()
       })
    }
    else {
        $scope.getElementDimensions()
    } 

$scope.getElementDimensions = function (){
    //whatever you actually wanted to do
}

link: function (scope, element, attrs) {
    $scope.tryGetElementDimensions()
}

Angular 在制作动画时添加了 ng-animate 和 ng-enter、ng-leave 类,当这些类全部被删除时,您可以确信它已经完成。没有第二个参数的 $timeout 只是等待下一个摘要。

【讨论】:

    【解决方案4】:

    还不能评论,所以这个答案。 找到了类似 strom2357 建议的类似解决方案。 $timeout 可以很好地让你知道 dom 何时准备就绪,而且非常简单。我正在使用这个解决方案来获取 ui-view 元素的宽度。找到它in a fiddle

    var app = angular.module('app', []);
    
    app.controller('MyController', function($timeout, $scope){
    
      $timeout(function(){
        //This is where you would get width or height of an element
        alert('DOM ready');
      });
    
      alert('DOM not ready');
    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      相关资源
      最近更新 更多