指令宽度(以像素为单位)

时间:2017-02-14 15:23:27

标签: jquery css angularjs

我一直在努力确定我正在声明指令的元素的宽度。

这是我的指令链接功能:

link: function (scope, elem, attrs) {
    var width = elem.width();
    scope.zoom = width / 674;
}

元素的宽度是父宽度的100%。我正在尝试获取整个页面加载和渲染完成后元素的宽度,包括此指令。我可以在我的元素检查器中看到它最终确定宽度(以像素为单位),而不是在我的角度过程的任何阶段。

非常感谢任何帮助。

注意:我已经尝试了许多使用$ timeout的不同方法,但是没有一个方法延迟这个过程足够长的宽度来设置像素。

更新1:

我误以为我在使用 ui-router 。我显然使用Angular的 ngRoute 。 (我真的应该知道这些事情,不好意思。)

无论如何,到目前为止,所提出的解决方案都没有产生可以解决的结果。甚至一些关于jQuery的官方文档也没有像他们想的那样简洁,所以我想我会分享更多的代码以期找出问题。

以下是我最近一次尝试后的完整指令:

(function () {
    'use strict';

    angular.module('app.widgets').directive('pagePreview', pagePreviewer);

    pagePreviewer.$inject = ['$window'];

    function pagePreviewer($window) {
        return {
            transclude: true,
            restrict: 'A',
            link: function (scope, elem, attrs) {
                scope.$on('$viewContentLoaded', function () {
                    scope.zoom = elem[0].clientWidth / 674;
                });

                //watch window resize
                angular.element($window).bind('resize', function () {
                    scope.zoom = elem[0].clientWidth / 674;
                    scope.$apply();
                });
            },
           templateUrl: 'app/widgets/pagePreviewer/pagePreviewer.html'
        }
    }
})();

调整大小功能正常,但 $ viewContentLoaded 事件永远不会触发。

我的模板如下:

<div>
    <style>
        .ft-page-container{
            position: relative;
            width:100%;
            padding-bottom:141%;
            border: 1px solid rgba(0, 0, 0, 0.25);
            box-shadow: 3px 3px 8px 1px rgba(0, 0, 0, 0.1);
        }
        .ft-page-container .ft-page{
            position: absolute;
            top: 0; left: 0; bottom: 0; right: 0;
            background-color: white;
            padding: 12% 14%;
        }
    </style>
    <div class="ft-page-container">
        <div data-ng-transclude class="ft-page" style="zoom: {{zoom}}; -moz-transform: scale({{zoom}});">
            <!-- Html gets injected here -->
        </div>
    </div>
</div>

我在 ngView 中使用该指令,在以下上下文中:

<!-- Preview -->
<div>
    <div id="invoice-template-preview" page-preview class="col-lg-offset-9 col-lg-3">
        Test
    </div>
</div>

我觉得我正在做一些非常基本的错误,因为在指令上获取计算的CSS /维度可能不太困难。特别是因为遵循Angular方式告诉你总是在指令中进行DOM操作,这通常很大程度上依赖于所说的计算值。

2 个答案:

答案 0 :(得分:0)

试试这个 - 你要检查的实际元素是包含elem的第一个对象。唯一的缺点是,当报告宽度时,它不包括边界的2px(每边1px)。我把它设为$timeout以确保它已经渲染,但在技术上可能没有必要。

angular.module('app', [])
  .directive('myDirective', function($timeout) {
    return {
      link: function(scope, elem, attrs) {
        $timeout(function() {
          console.log(elem[0].clientWidth)
        });
      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="app">
  <div style="width:100%; height: 50px; border: 1px solid black;" my-directive></div>
</div>

答案 1 :(得分:0)

以下是您尝试实现的working plnkr,例如调用Page1 )。触发$scope.zoom时以及$viewContentLoaded尺寸更改时,$window会更新。{/ p>

State1视图

<div>
     <div>
         <h1>Page 1 content goes here...</h1>
        <div class="outer">
          <div class="inner" sizer>
             {{ zoom }}
          </div>
      </div>
     </div>
</div>

AngularJS应用程序

var myApp = angular.module("myApp", ['ui.router']);

myApp.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.when("", "/PageTab");

    $stateProvider
        .state("PageTab", {
            url: "/PageTab",
            templateUrl: "PageTab.html"
        })
        .state("PageTab.Page1", {
            url: "/Page1",
            templateUrl: "Page1.html"
        })
        .state("PageTab.Page2", {
            url: "/Page2",
            templateUrl: "Page2.html"
         })
        .state("PageTab.Page3", {
            url: "/Page3",
            templateUrl: "Page3.html"
        });
});

myApp.directive('sizer', function($window) {
        return {
            link: function(scope, elem, attrs) {

              scope.$on('$viewContentLoaded', function () {
                  scope.zoom = elem[0].clientWidth / 674;
              });

              //watch window resize
              angular.element($window).bind('resize', function () {
                  scope.zoom = elem[0].clientWidth / 674;
                  scope.$apply();
              });
            }
        };
    });