Get incorrect offsetWidth and offsetHeight values

后端 未结 3 2076
眼角桃花
眼角桃花 2021-02-08 06:36

Here is my angular2 code.

Template

3条回答
  •  南笙
    南笙 (楼主)
    2021-02-08 07:12

    You can detect size changes by using

    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! ).

    Here is how you can use it to detect changes in elements :

    // 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();
    

    For your case, you could use it inside your ngAfterViewInit and refresh your offsets size. You can be more specific and only detect some mutations, and only then extract your offsets.

    more info :

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

    compatibility : https://caniuse.com/#feat=mutationobserver

    Demo:

    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;
    }
    I am a demo div
    logs :

提交回复
热议问题