Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getBoundingClientRect() Object properties cannot be copied [duplicate]

function test(o) {
    console.log("Object:", o);
    console.log("Assign test:", Object.assign({}, o));
    console.log("Keys test:", Object.keys(o));
    console.log("JSON test:", JSON.stringify(o));
}

var el = document.getElementById("question");                 /* or document.body */

test(el.style);                                               /* works as expected */
test(el.getBoundingClientRect());                             /* behaves like {} */
test(Object.assign(el.getBoundingClientRect(),{aaaa: 1111})); /* works... only for aaaa */

Why?

Output (test results)

See PasteBin.

MDN documentation

  1. Element.getBoundingClientRect()
  2. DOMRect
like image 767
7vujy0f0hy Avatar asked Oct 15 '25 02:10

7vujy0f0hy


1 Answers

Object.assign and Object.keys are working with own enumerable properties. DOMRect properties are inherited from DOMRectPrototype and cannot be accessed by those methods.

You can prove that by:

let rect = el.getBoundingClientRect();
rect.hasOwnProperty('x');                        // === false
Object.getPrototypeOf(rect).hasOwnProperty('x'); // === true

I used Lodash _.assignIn which iterates over own and inherited source properties:

https://jsfiddle.net/msazmfxo/

UPDATE

Based on this answer, 7vujy0f0hy found the acceptable solution:

var ownify = input => 
               Object.keys(Object.getPrototypeOf(input)).reduce((output,key) => 
                 Object.assign(output, {[key]: input[key]}), Object.assign({}, input));

test(ownify(el.getBoundingClientRect())); /* apparently works! */

(Although it iterates only over one level of inheritance, attributes from deeper levels will be still missing)

like image 154
phts Avatar answered Oct 16 '25 16:10

phts



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!