Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getBoundingClientRect to detect visibility

Background: I'm currently working on a project where my JS app is embedded into multiple other (parent) JS applications. Some parent app can show/hide my app by setting display:block/none to some element that contains my app. Other parent apps temporarily remove my app from DOM and reattach it later. Few parent apps use shadow dom, so I do not have the access to the elements in the parent app.

I need a way to check if my app is visible (inside DOM and displayed; don't care about visibility:hidden and doesn't have to be inside the viewport), without changing the parent apps, so I looked into getBoundingClientRect.

Question: At least on chrome, getBoundingClientRect returns (w:0,h:0,l:0,t:0) if an element or its ancestor has display:none or if it is removed from DOM. I could not find any documentation on the guarantee of this behavior, and I am wondering, if it is safe (in the sense the this logic will not change) to use getBoundingClientRect to check for visibility of an element.

Also I need to know if this behavior is consistent across all major browsers, including FF, IE8+, and Safari. Is this documented anywhere?

Lastly, why (0,0,0,0)? I feel like getBoundingClientRect should return null in such cases as (0,0,0,0) actually means something different. Is there a good reason for that?


Edited/Additional Question: Thanks istos for pointing out that returning null may break some unsuspecting code, such as:

console.log(clientRectObject.height);
// TypeError: Cannot read property 'height' of null

Not to complain about the current behavior, but as a design question: instead of null, can returning some illegal Rect values (such as negative width and height) be a more useful alternative?

like image 995
haejeong87 Avatar asked Oct 20 '22 18:10

haejeong87


1 Answers

First I would look into how popular libraries like jQuery solve a similar problem. Here are some links to jQuery's source:

  • https://github.com/jquery/jquery/blob/master/src/css/var/isHidden.js
  • https://github.com/jquery/jquery/blob/master/external/sizzle/dist/sizzle.js#L715
  • https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js

Further more I would search online for any clues including MDN:

  • https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
  • http://www.nczonline.net/blog/2008/02/04/getting-element-dimensions-a-follow-up
  • http://ejohn.org/blog/getboundingclientrect-is-awesome
  • http://www.quirksmode.org/blog/archives/2008/02/the_cssom_view.html#link5

Unfortunately the best way to check if the behavior of getBoundingClientRect is the same in most Browsers is to actually test inside those Browsers. If you do this, please go back to MDN and add your findings.


I feel like getBoundingClientRect should return null in such cases

Although returning null would seem logical in such cases, it isn't actually ideal because normally it returns a ClientRect object with top, right, bottom, left, width, and height properties, and code like this would break:

console.log(clientRectObject.height);
// TypeError: Cannot read property 'height' of null

In other words, the API wouldn't be consistent that way.

like image 156
istos Avatar answered Oct 22 '22 07:10

istos