How best to convert a ClientRect / DomRect into a plain Object
Solution 1
Let's not overcomplicate things!
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 )
)
Solution 2
This is something that I can live with:
const persistRect = JSON.parse(JSON.stringify(someElement.getBoundingClientRect()))
Solution 3
Warning: non-standard behavior (doesn't work in Firefox < 62, including ESR 60 and possibly other browsers other than Chrome)
var obj = el.getBoundingClientRect().toJSON();
Solution 4
You could use the extend method if you are using jQuery.
var obj = $.extend( {}, element.getBoundingClientRect());
Solution 5
Functional ES6 variant:
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())
Related videos on Youtube
Zach Lysobey
Updated on October 04, 2022Comments
-
Zach Lysobey over 1 year
The result of
someElement.getBoundingClientRect()
returns a special object of typeClientRect
(orDomRect
apparently)It is structured like
{top: 10, right: 20, bottom: 30, left: 10, width: 10}
Unfortunately, this object does not behave quite like other objects.
For example, using
Object.keys
on it returns an empty array (I think becauseClientRect
properties are not enumerableI found something of a dirty way to convert to a plain object:
var obj = {} for (key in rect) { obj[key] = rect[key] }
My question is, is there a better way?
-
Joseph Marikle over 7 yearsThis is soooo hacky, but
Object.keys(document.body.getBoundingClientRect().__proto__)
seems to work in chrome. :P -
Gust van de Wal about 2 yearsMake that
Object.keys(Object.getPrototypeOf(document.body.getBoundingClientRect()))
and it isn't as hacky anymore
-
-
kamelkev about 7 yearsThis can and does work, but $.extend is notoriously inefficient compared to various other cloning methods. See jsben.ch/#/bWfk9. As OP notes ClientRect is a special object though, and most (all?) other techniques do not work as expected, so not a lot of choices here.
-
aboutaaron almost 7 yearsHere's an ES6 version:
const getBoundingClientRect = (element) => { const {top, right, bottom, left, width, height, x, y} = element.getBoundingClientRect(); return {top, right, bottom, left, width, height, x, y} }
-
Zach Lysobey about 6 yearsI think you don't even need the
Object.assign
there..toJSON
retuns a proper object (Object.keys($0.getBoundingClientRect().toJSON())
works). You get a fresh object every time too!$0.getBoundingClientRect().toJSON() !== $0.getBoundingClientRect().toJSON()
-
mkg about 6 yearskeep in mind,
toJSON
is not working for rect objects at firefox folks -
Yami Odymel almost 6 yearsSorry, but I have to downvote the answer since you didn't mention it doesn't support with Firefox
-
Fredrik_Borgstrom over 4 yearsDoesn't work in Edge. But when Edge switches to Chromium, that will be resolved.
-
Michael Johansen over 2 yearsAs a general rule, one should avoid converting numbers to strings (and back) unless necessary. String operations are a lot more expensive that working with numbers, so if you have to do this operation many times performance will suffer.
-
Skyrocker over 2 years@MichaelJohansen, completely agree, good remark