Jsdom: Implement `element.getBoundingClientRect` and `element.getClientRects`

Created on 5 Jul 2013  ·  18Comments  ·  Source: jsdom/jsdom

Related to #61 and #135.

Not so sure this is possible based on discussion so far in those issues but I thought I'd throw it out there.

css

Most helpful comment

for testing, if you control the elements, you can also override per instance.

example:

function createMockDiv (width, height) {
  const div = document.createElement("div");
  Object.assign(div.style, {
    width: width+"px",
    height: height+"px",
  });
  // we have to mock this for jsdom.
  div.getBoundingClientRect = () => ({
    width,
    height,
    top: 0,
    left: 0,
    right: width,
    bottom: height,
  });
  return div;
}

All 18 comments

I think getBoundingClientRect should at least be implemented as a dummy function that returned default values.

That seems reasonable; zeros for everything and all that. Patch welcome.

Thanks, @F1LT3R and @domenic! (Although, in the meanwhile, I actually already moved on to port these tests from nodeunit to an appropriate web-based framework: QUnit). :+1:

Does getClientRects work in jsdom? According to this jquery ticket, it does not

getClientRects is not supported, only getBoundingClientRect. A PR adding getClientRects() that always returns an empty array (or maybe an array with a single rect with zeroes for all its values??) would be great.

Yeah jquery 1.12.0 just updated its core style function to use getClientRects. We ran into the same issue. I may be able to look into doing a PR adding this on monday. In our case it was the .height() function that is now throwing.

I haven't been able to get the correct values from el.getBoundingClientRect(). The object that gets returned has all of the correct keys (height, width, top, etc) but every value is always 0. I'm interested to know if anyone else is experiencing this.

This always fails:

    it('getBoundingClientRect produces correct height', () => {
      container.style.height = '300px'
      expect(container.getBoundingClientRect().height).eql(300)
    })

My workaround to make my tests pass (which is a phrase that pains me to say) is something like this:

getComputedElHeight(el) {
    return Number(window.getComputedStyle(el).height.split('px')[0])
  }

Just thought I'd share while this issue is still open.

I don't think it was implemented to have the correct values. I think it was
implemented to have the correct attributes only.
On Mar 14, 2016 9:02 AM, "lushfuture" [email protected] wrote:

I haven't been able to get the correct values from
el.getBoundingClientRect(). The object that gets returned has all of the
correct keys (height, width, top, etc) but every value is always 0. I'm
interested to know if anyone else is experiencing this.

This always fails:

it('getBoundingClientRect produces correct height', () => {
  container.style.height = '300px'
  expect(container.getBoundingClientRect().height).eql(300)
})

My workaround to make my tests pass (which is a phrase that pains me to
say) is something like this:

getComputedElHeight(el) {
return Number(window.getComputedStyle(el).height.split('px')[0])
}

Just thought I'd share while this issue is still open.


Reply to this email directly or view it on GitHub
https://github.com/tmpvar/jsdom/issues/653#issuecomment-196300151.

Yes, making it return real values would essentially require implementing a whole layout engine which would be a massive undertaking. Issue #1322 covers that topic.

Is it possible in tests to override that method (for all elements) to get a usable value while testing code that uses it?

Yes, the same way you would in a browser: Element.prototype.getBoundingClientRect = function () { ... }

I ended up doing
window._core. HTMLDivElement.prototype.getBoundingClientRect

Which worked just fine.

That will break in future releases of jsdom (very soon, actually). Just remove the ._core.

Thanks I'll try that
On Sep 2, 2016 9:03 PM, "Domenic Denicola" [email protected] wrote:

That will break in future releases of jsdom (very soon, actually). Just
remove the _core.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/tmpvar/jsdom/issues/653#issuecomment-244520584, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AEtD9luz1uJWmJ3JlgdwuO1i5MP04_BXks5qmNWCgaJpZM4Ayv3U
.

for testing, if you control the elements, you can also override per instance.

example:

function createMockDiv (width, height) {
  const div = document.createElement("div");
  Object.assign(div.style, {
    width: width+"px",
    height: height+"px",
  });
  // we have to mock this for jsdom.
  div.getBoundingClientRect = () => ({
    width,
    height,
    top: 0,
    left: 0,
    right: width,
    bottom: height,
  });
  return div;
}

how to write karma code if getboundingclientrect() method is in if else condition in ts file.
can anyone please help.

window.HTMLElement.prototype.getBoundingClientRect = function () {
  return {
    width: parseFloat(this.style.width) || 0,
    height: parseFloat(this.style.height) || 0,
    top: parseFloat(this.style.marginTop) || 0,
    left: parseFloat(this.style.marginLeft) || 0
  }
}

and also this for offset

Object.defineProperties(window.HTMLElement.prototype, {
  offsetWidth: {
    get () { return parseFloat(this.style.width) || 0 }
  },
  offsetHeight: {
    get () { return parseFloat(this.style.height) || 0 }
  },
  offsetTop: {
    get () { return parseFloat(this.style.marginTop) || 0 }
  },
  offsetLeft: {
    get () { return parseFloat(this.style.marginLeft) || 0 }
  }
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

potapovDim picture potapovDim  ·  4Comments

JacksonGariety picture JacksonGariety  ·  4Comments

josephrexme picture josephrexme  ·  4Comments

Progyan1997 picture Progyan1997  ·  3Comments

mitar picture mitar  ·  4Comments