Monsieur Pierre Doune
Monsieur Pierre Doune

Reputation: 737

Find All Visible Elements in a Container

How to find all elements within some container, that are visible to the user?

Maybe there is some kind of a querySelector exists that searches only in a visible area?

Also, it will be fine if black_magic would return an element closest to the horizontal screen center.

function black_magic( ) {
    /* your code goes here */
};

button.onclick = function( ) {
    const visible_elements = black_magic();
    console.log( visible_elements );
};
:root {
    background: linear-gradient( #e66465, #9198e5 );
}

button {
    position: fixed;
    top: 0.5rem;
}

#container {
    display: flex;
    flex-direction: column;
}

#container > section {
    background: linear-gradient( #9198e5,  #e66465 );
    padding: 0.5rem;
    text-align: center;
    color: white;
    font-size: xx-large;
    margin: 1rem 0 1rem 0;
}
<html>
<head></head>
<body>
    <button id=button>Check for Visible Elements in #container</button>
    <section id=container>
        <section>Hello, World! #01</section>
        <section>Hello, World! #02</section>
        <section>Hello, World! #03</section>
        <section>Hello, World! #04</section>
        <section>Hello, World! #05</section>
        <section>Hello, World! #06</section>
        <section>Hello, World! #07</section>
        <section>Hello, World! #08</section>
        <section>Hello, World! #09</section>
        <section>Hello, World! #10</section>
        <section>Hello, World! #11</section>
        <section>Hello, World! #12</section>
        <section>Hello, World! #13</section>
        <section>Hello, World! #14</section>
        <section>Hello, World! #15</section>
        <section>Hello, World! #16</section>
    </section>
</body>
</html>

Upvotes: 2

Views: 651

Answers (1)

Matthias Gwiozda
Matthias Gwiozda

Reputation: 595

This sould do the trick.

function black_magic( ) {
    const allElements = document.querySelectorAll('#container *');
    let elements = [];
    allElements.forEach(function(node){
      let clientRect = node.getBoundingClientRect();
      if (!(window.innerHeight <= clientRect.top || (clientRect.top <= 0 && clientRect.bottom <= 0)) ) {
        elements.push(node);
      }
    });
    return elements;
};

button.onclick = function( ) {
    const visible_elements = black_magic();
    console.log( visible_elements );
};
:root {
    height: 2000px;
    background: linear-gradient( #e66465, #9198e5 );
}

button {
    position: fixed;
    top: 0.5rem;
}

#test_element {
    background: linear-gradient( #9198e5,  #e66465 );
    padding: 0.5rem;
    text-align: center;
    color: white;
    font-size: xx-large;
    margin-top: 1000px;
}
<html>
<head></head>
<body>
    <button id=button>Check for Visible Elements in #container</button>
    <section id=container>
        <section id=test_element>
            Hello, World!
        </section>
    </section>
</body>
</html>

See: https://stackoverflow.com/a/18794913/6458608, https://stackoverflow.com/a/3333352/6458608:

Upvotes: 2

Related Questions