24

的结果someElement.getBoundingClientRect()返回一个特殊类型的对象ClientRect(或DomRect显然)

它的结构类似于{top: 10, right: 20, bottom: 30, left: 10, width: 10}

不幸的是,这个对象的行为与其他对象不同。

例如,使用Object.keys它返回一个空数组(我认为因为ClientRect属性不是枚举

我发现了一种转换为普通对象的肮脏方式:

var obj = {}
for (key in rect) {
  obj[key] = rect[key]
}

我的问题是,有没有更好的方法?

4

6 回答 6

26

让我们不要把事情复杂化!

function getBoundingClientRect(element) {
  var rect = element.getBoundingClientRect();
  return {
    top: rect.top,
    right: rect.right,
    bottom: rect.bottom,
    left: rect.left,
    width: rect.width,
    height: rect.height,
    x: rect.x,
    y: rect.y
  };
}

ES2015:

const getBoundingClientRect = element => { 
  const {top, right, bottom, left, width, height, x, y} = element.getBoundingClientRect()
  return {top, right, bottom, left, width, height, x, y} 
}

console.log(
  getBoundingClientRect( document.body )
)

于 2016-09-09T19:14:49.440 回答
5

警告:非标准行为(不适用于Firefox < 62,包括 ESR 60 和可能的 Chrome 以外的其他浏览器)

var obj = el.getBoundingClientRect().toJSON();
于 2018-02-05T21:51:12.127 回答
5

这是我可以忍受的:

const persistRect = JSON.parse(JSON.stringify(someElement.getBoundingClientRect()))
于 2019-05-08T18:00:28.373 回答
4

如果你使用 jQuery,你可以使用extend方法。

var obj = $.extend( {}, element.getBoundingClientRect());
于 2016-12-02T11:17:03.953 回答
2

功能性 ES6 变体:

const propValueSet = (prop) => (value) => (obj) => ({...obj, [prop]: value})
const toObj = keys => obj => keys.reduce((o, k) => propValueSet(k)(obj[k])(o), {})
const getBoundingClientRect = el => toObj(['top', 'right', 'bottom', 'left', 'width', 'height', 'x', 'y'])(el.getBoundingClientRect())
于 2019-07-01T19:38:52.713 回答
1

你可以Object.fromEntries()用来创建你的 obj.

let domRec = document.getElementById('test').getBoundingClientRect();

// Convert to plain Object
let domObj = Object.fromEntries(Array.from(Object.keys(DOMRectReadOnly.prototype).filter(k => !isNaN(domRec[k])), k => [k, domRec[k]]));

// Convert back to DOMRectReadOnly
let domRec2 = DOMRectReadOnly.fromRect(domObj);

console.log('DOMRectReadOnly', domRec);
console.log('Plain Object', domObj);
console.log('DOMRectReadOnly', domRec2);
#test {
  width: 200px;
  height: 50px;
  background-color: #f00;
}
<div id="test"></div>

但是,这也会将toJSONfn 复制到新的 obj 中。因此我建议过滤非数字值:.filter(k => !isNaN(domRec[k]).

轻的

如果您只对x, y, width,感兴趣height,您可以使用DOMRect而不是DOMRectReadOnly跳过该.filter()部分。

您可以从这 4 个值中计算bottom,的值,并且,只是,的别名。rightlefttopxy

let domRec = someElement.getBoundingClientRect();
let domObj = Object.fromEntries(Array.from(Object.keys(DOMRect.prototype), k => [k, domRec[k]]));
于 2021-09-21T23:13:51.477 回答