0

How might one go about getting all controls visible to the user?

<div id=dataform>
  <div>
    Name
    <input type=text id=name class=entry>
  </div>

  <div>
    City
    <input type=text id=city class=entry style="display:none;">
  </div>

  <div style="display:none;">
    <label for=nocontact>nocontact</label>
    <input type=checkbox id=nocontact class=entry>
  </div>

  <div>
    <table>
      <tr>
        <td>
          <label for=phone>Phone</label>
        </td>
        <td>
          <input type=text id=phone class=entry>
        </td>
      </tr>
    </table>
  </div>

  <div>
    <select id="keys">
      <option value=1>1</option>
      <option value=2>2</option>
      <option value=3>3</option>
  </div>
</div>

Neither "city" nor "nocontact" are visible to the user.

document.getElementById("dataform").querySelectorAll("dataform > entry ???? ");

Or some other method to get all controls, inputs, that are visible (not just inputs, but selects, textarea, etc). Could add a class to each, as shown and grab all, but how to determine or get just those that are visible to the user. The nocontact checkbox wouldn't be, so ignore it. I put the table in there to demonstrate that the control is not always a direct child of the div in which it resides.

I'm afraid that cycling through them all and tagging them with a class or a data attribute is the only way and that pretty much sucks. FYI: not using jquery or other framework on this.

Erick
  • 369
  • 3
  • 13
  • Just query for all elements and filter out the ones with style.display set to none, if that's all you mean by visible. – Ruan Mendes Feb 07 '20 at 21:28
  • Does this answer your question? [Get only visible element using pure javascript](https://stackoverflow.com/questions/44612141/get-only-visible-element-using-pure-javascript) – Arber Sylejmani Feb 07 '20 at 21:34
  • Similar answer to below - would get where control has a display or visibility is explicitly set on the control, but would lose those that are not visible-to-the-user because a parent is not shown. – Erick Feb 07 '20 at 22:03
  • The answer Arber linked to may not have a satisfactory answer, but it's essentially the same question. There are also several other questions that are materially the same. – Brilliand Feb 07 '20 at 22:26
  • Does this answer your question? [Check if element is visible in DOM](https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom) – Brilliand Feb 07 '20 at 22:29
  • (No not really, but the question is the same.) – Brilliand Feb 07 '20 at 22:36
  • It might be the same question, but when looking for an entirely different result that suggests that one or both of the questions should offer more clarity to increase the distinction. :-) – Erick Feb 08 '20 at 04:53

1 Answers1

1

There's no "proper" way to do this, in part because it's unclear what "visible" is supposed to mean in the first place. jQuery (version 3.4.1) does it like this:

jQuery.expr.pseudos.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

...which is great for certain definitions of "visible", but it doesn't check whether an element has "visibility" set to "hidden", or if it's scrolled off the screen; it mostly just checks for display:none (including on parent elements).

Brilliand
  • 13,404
  • 6
  • 46
  • 58
  • That would be effective, I think, to get stuff that's within the viewport, but setting visibility:hidden or display:none wouldn't pick up and if either were set on a parent, it also wouldn't work. – Erick Feb 07 '20 at 22:02
  • 1
    @Erick This does catch `display:none`, including if it's set on a parent. In that case the `offsetWidth` and `offsetHeight` will both be 0. – Brilliand Feb 07 '20 at 22:06
  • @Brilland that's an interesting idea. I'll play with it. Thanks. – Erick Feb 08 '20 at 04:52
  • Whoops, this doesn't actually check if an element is scrolled off the screen; it pretty much *only* checks for `display:none` on the element or any parent. – Brilliand Feb 10 '20 at 21:57
  • It works for me. I'm not worried about visibility within the viewport, but generally on the page. I'm using it and it works. :-) – Erick Feb 12 '20 at 06:23