[英]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.