繁体   English   中英

获取不正确的 offsetWidth 和 offsetHeight 值

[英]Get incorrect offsetWidth and offsetHeight values

这是我的 angular2 代码。

模板

 <div #picker class="slider"> <div class="slider-track"> <div #sliderSelectionEl class="slider-selection"></div> <div #sliderHandle1 class="slider-handle"></div> <div #sliderHandle2 class="slider-handle"></div> </div> <div #tooltipEl class="tooltip"> <div class="tooltip-arrow"></div> <div #tooltipInner class="tooltip-inner"></div> </div> <input type="text" class="span2" value="" id="sl2"><br/> </div>


成分

import {Component, OnInit, Input, ViewChild, ElementRef, Renderer} from '@angular/core';
    export class SliderComponent implements OnInit {
      @ViewChild('picker') picker: ElementRef;

      constructor(private renderer: Renderer, private el: ElementRef) {

      }

      ngAfterViewInit() {
        this.renderer.setElementClass(this.picker.nativeElement, 'slider-horizontal', true);

        console.log(this.picker.nativeElement.offsetWidth);
        console.log(this.picker.nativeElement.offsetHeight);
      }
    }

 .slider-horizontal { width: 210px; height: 20px; }

问题是每次加载时打印的值都不同。 我猜这个问题是由于浏览器没有完成加载div。 你知道解决这个问题的方法是什么吗?

您可以使用以下方法检测尺寸变化

突变观察者

可能这个新 api 的最大受众是编写 JS 框架的人,[...] 另一个用例是您使用框架来操作 DOM 并且需要有效地对这些修改做出反应的情况(并且没有 setTimeout hacks! )。

以下是如何使用它来检测元素的变化:

// select the target node
var target = document.querySelector('#some-id'); // or 

// create an observer instance
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log(mutation.type);
    });
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true }

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();

对于您的情况,您可以在ngAfterViewInit使用它并刷新您的偏移量大小。 您可以更具体,只检测一些突变,然后才提取您的偏移量。

更多信息 :

文档: https : //developer.mozilla.org/en-US/docs/Web/API/MutationObserver

兼容性: https : //caniuse.com/#feat=mutationobserver

演示

 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation); if(mutation.attributeName == 'class') // detect class change /* or if(mutation.target.clientWidth == myWidth) */ showOffset(mutation.target); observer.disconnect(); }); }); var config = { attributes: true} var demoDiv = document.getElementById('demoDiv'); var logs = document.getElementById('logs'); // wait for document state to be complete if (document.readyState === "complete") { ngAfterViewInit(); } document.onreadystatechange = function () { if (document.readyState === "complete") { ngAfterViewInit(); } } // observe changes that effects demoDiv + add class function ngAfterViewInit(){ observer.observe(demoDiv, config); demoDiv.classList.add('slider-horizontal'); } // show offsetWidth + height. // NB offset width and height will be bigger than clientWidth because I added a border. If you remove the border you'll see 220px,20px function showOffset(element){ offsetMessage = "offsetWidth:" + demoDiv.offsetWidth + " offsetHeight: " + demoDiv.offsetHeight; console.log(offsetMessage); logs.innerHTML = offsetMessage; }
 .slider-horizontal { border: 2px solid red; width: 210px; height: 20px; background: grey; }
 <div id='demoDiv'> I am a demo div </div> <div style="margin-top: 20px;"> logs : <span id='logs' style=" padding: 5px; border: 1px solid black"></span></div>

您必须在渲染周期后安排对 'offsetWidth' 的调用,angular 在微任务队列的末尾执行 draw,因此您可以尝试setTimeout(..., 0)或在Promise.resolve().then(...)运行Promise.resolve().then(...) zonejs 的。 希望能帮助到你。

为了获得正确的偏移值,您可以使用: ngAfterContentChecked 和 AfterContentChecked 接口。

每次更改检测运行后都会调用此方法。 因此,在此方法中使用标志(或计数器)和 setTimeOut:

if (this.counter <= 10) {
      // this print offsetwidth of my element
      console.log('mm ' + this.container.nativeElement.offsetWidth);


      // setTimeOut allow to run another changedetection 
      // so ngAfterContentChecked will run again
      setTimeout(() => { }, 0);

      //you could use a counter or a flag in order to stop getting the right width
      this.counter++;
    }

希望能帮助到你! 随意评论

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM