html - 获取不正确的 offsetWidth 和 offsetHeight 值

标签 html angular

这是我的 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。你知道解决这个问题的方法是什么吗?

最佳答案

您可以使用

检测尺寸变化

MutationObserver

Probably the biggest audience for this new api are the people that write JS frameworks, [...] Another use case would be situations where you are using frameworks that manipulate the DOM and need to react to these modifications efficiently ( and without 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. 
// N.B 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>

关于html - 获取不正确的 offsetWidth 和 offsetHeight 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41674184/

相关文章:

javascript - 内容和页脚重叠而不是将页脚推到底部

html - iframe 在仅限 iOS 的设备上没有响应

python - pandas DataFrame to_html 中的粗体列

angular - 如何在 Angular 5 的 Mat-Select 选项中获取所选值的 ID

javascript - 更改 @Input 组件对象不会反射(reflect)在父组件中

angular - 如何在 Angular 6 中选择原生元素的 ContentChild?

javascript - Switch 语句不适用于某些变量

java - 正则表达式从文件中获取所有 ".js"和 ".css"href 链接

html - Safari 6 - 影响整个表单的自动完成

javascript - 在 ng-template 中访问 FormArray 引用