Efficiently get an element's visible area coordinates Efficiently get an element's visible area coordinates jquery jquery

Efficiently get an element's visible area coordinates


Try

var res = [];$("body *").each(function (i, el) {    if ((el.getBoundingClientRect().bottom <= window.innerHeight         || el.getBoundingClientRect().top <= window.innerHeight)        && el.getBoundingClientRect().right <= window.innerWidth) {            res.push([el.tagName.toLowerCase(), el.getBoundingClientRect()]);    };});

jsfiddle http://jsfiddle.net/guest271314/ueum30g5/

See Element.getBoundingClientRect()

$.each(new Array(180), function () {    $("body").append(    $("<img>"))});$.each(new Array(180), function () {$("body").append($("<img>"))});var res = [];$("body *").each(function (i, el) {if ((el.getBoundingClientRect().bottom <= window.innerHeight || el.getBoundingClientRect().top <= window.innerHeight)    && el.getBoundingClientRect().right <= window.innerWidth) {    res.push(    [el.tagName.toLowerCase(),    el.getBoundingClientRect()]);    $(el).css(        "outline", "0.15em solid red");    $("body").append(JSON.stringify(res, null, 4));    console.log(res)};});
body {    width : 1000px;    height : 1000px;}img {    width : 50px;    height : 50px;    background : navy;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


I don't know if the performance will be sufficient (especially on a mobile device), and the result is not quite a rectangle-set as you requested, but did you consider using a bitmap to store the result?

Note some elements may have 3d css transform (eg. skew, rotate), some elements may have border radius, and some elements may have invisible background - if you want to include these features as well for your "element from pixel" function then a rectangle set can't help you - but the bitmap can accommodate all of the visual features.

The solution to generate the bitmap is rather simple (I imagine... not tested):

  1. Create a Canvas the size of the visible screen.
  2. iterate over all the elements recursively, sorted by z-order, ignore hidden
  3. for each element draw a rectangle in the canvas, the color of the of the rectangle is an identifier of the element (eg. could be incremental counter). If you want you can modify the rectangle based on the visual features of the element (skew, rotate, border radius, etc...)
  4. save the canvas as lossless format, eg png not jpg
  5. send the bitmap as the meta data of elements on screen

To query which element is at point (x,y) you could check the color of the bitmap at pixel (x,y) and the color will tell you what is the element.


If you can jettison IE, here's a simple one:

function getElementVisibleRect(el) {  return new Promise((resolve, reject) => {    el.style.overflow = "hidden";    requestAnimationFrame((timeStamp) => {      var br = el.getBoundingClientRect();      el.style.overflow = "";      resolve(br);    });  });}

Even then, Promises are easily polyfillable and requestAnimationFrame() works as far back as IE 8. And by 2016, the only thing you should bother to give any poor souls on older IE is a legible experience.