4

Chrome Platfrom announces that it will deprecate offsetWidth soon. And it suggests developers to use getBoundingClientRect() instead.

But when there is a scale, they are different.

<div id="wrap"  style="transform: scale(2); width:300;height:300;">
   <svg id="real" style="border:red 10px solid;" >
     <rect/>
   </svg>
</div>

<script>
var e = document.getElementById("real");
var rect = e.getBoundingClientRect(); 
console.log(e.offsetWidth);  //320
console.log(e.clientWidth);  //300
console.log(rect.width);     //640   
</script>      

In my another question, I tried to find an official API to get the scale but failed.

How to replace the deprecated "svgElement.offsetWidth/height/parent" on Chrome when there is a scale?

One way I can think is to get the border width and add it to clientWidth. Is there a api to get svg border? Using e.style.borderRightWidth and doing the string parsing doesn't look nice.

Any answer or comment will be appreciated.

Community
  • 1
  • 1
hjyssg
  • 61
  • 1
  • 4

1 Answers1

0

One way would be to remove to transform for all ancestors, calcualte the client rect, and then restore the transform of the ancestors:

function getOffsetWidth(elm) {
  var cur, i;
  var saveTransforms = [];

  i = 0;
  cur = elm;
  //set the transform to '' for all ancestors
  while (cur) {
    if (cur.style) {
      saveTransforms[i] = cur.style.transform;
      cur.style.transform = '';
    }
    i++;
    cur = cur.parentNode;
  }
  var rect = e.getBoundingClientRect();

  i = 0;
  cur = elm;


  //restore the transform for all ancestors
  while (cur) {
    if (cur.style) {
      cur.style.transform = saveTransforms[i];
    }
    i++;
    cur = cur.parentNode;
  }


  return rect.width;
}

Here the updated jsfiddle

t.niese
  • 39,256
  • 9
  • 74
  • 101