Accessing only the visible elements using vanilla JavaScript

Here are some elements I have:

<div class="one">send Message</div>

<div class="one">send Message</div>

<div class="one">send Message</div>

In a web page, there are send buttons like the ones above. Only one button is visible at a time, while the other two are hidden using JavaScript. For example, if the second button is visible, I want to access only that specific element.

My code would look something like this:

document.querySelector(".one:visible");

Using jQuery, the code would be $(".one:visible");, which works well. However, I am interested in how to achieve this using pure JavaScript.

Answer №1

Check out this Javascript code snippet for identifying hidden elements:

// Iterate through all elements on the page (modify to target specific DOM element)
var allElements = document.getElementsByTagName("*");

for (var index = 0, totalElements = allElements.length; index < totalElements; index++) {
    if (isElementHidden(allElements[index]))
        // Element is hidden
    else 
        // Element is visible
}

function isElementHidden(element) {
    var style = window.getComputedStyle(element);
    return ((style.display === 'none') || (style.visibility === 'hidden'))
}

Answer №2

I wanted to share a more concise alternative:

const elements = Array.from(document.querySelectorAll('.one')).filter(el =>
   window.getComputedStyle(el).getPropertyValue('display') != 'none'
);

This code snippet retrieves all elements where the CSS property display: block is applied.

Answer №3

To accurately determine the height and width of an element, you can utilize the getBoundingClientRect method. This method will provide values of zero if the element is not currently in the DOM or if it is not being displayed.

It's important to note that using getBoundingClientRect won't help you identify whether an element is invisible due to CSS properties like visibility: hidden or opacity: 0. In such cases, jQuery also employs similar approaches through :visible selector by checking for offsetHeight and offsetWidth values of zero.

In addition, while this method can confirm visibility within the viewport, it may not detect if the element is obscured by other elements on the page. However, with some additional logic, you could address these scenarios as well.

For further insights on detecting element visibility without relying on jQuery, refer to this resource.

Answer №4

var $el = document.querySelectorAll('.one');
var visibleElements;

for (var i = 0; i < $el.length; i++) {
    var currentElement = $el[i];
    var $style = window.getComputedStyle(currentElement, null);

    if (!currentElement) {
        return false;
    } else if (!$style) {
        return false;
    } else if ($style.display === 'none') {
        return false;
    } else {
        visibleElements.push(currentElement);
    }
}

We start by selecting all elements using document querySelectorAll. Then, there is a loop to iterate through each element and check its visibility using getComputedStyle.

The visibility check in the first code snippet only considers display property. In the second code snippet, we have a function that checks for various visibility aspects including display, visibility, opacity, height, overflow, and position.

This function provides a more comprehensive approach to checking an element's visibility in the DOM, covering many scenarios except for z-index cases.

Answer №5

For those who opt to utilize the hidden attribute:

document.querySelector(".one:not([hidden])");

Answer №6

jQuery's :visible selector simply checks the display property to determine visibility status.

(window.getComputedStyle(el).getPropertyValue('display') !== 'none')

While this may suffice for basic needs, it falls short in more complex scenarios. For a thorough solution, continue reading.

Utilizing both Element.getBoundingClientRect() and window.getComputedStyle() can effectively detect element visibility within the viewport.

Solely relying on getBoundingRect() or getComputedStyle() is not optimal for performance. Combining these two functions yields the best results (approximately 22% faster than using getComputedStyle() alone).

function inViewport(els) {
    let matches = [],
        elCt = els.length;

    for (let i=0; i<elCt; ++i) {
        let el = els[i],
            b = el.getBoundingClientRect(), c;

        if  (b.width > 0 && b.height > 0 &&
            b.left+b.width > 0 && b.right-b.width < window.outerWidth && 
            b.top+b.height > 0 && b.bottom-b.width < window.outerHeight && 
            (c = window.getComputedStyle(el)) &&
            c.getPropertyValue('visibility') === 'visible' &&
            c.getPropertyValue('opacity') !== 'none') {
            matches.push(el);
        }
    }
    return matches;
}

Here's an example of how to use this function...

var els = document.querySelectorAll('.one'),
    visibleEls = inViewport(els);

This method ensures that elements are not hidden (display set to "none"), visible in the viewport, with positive dimensions, and fully contained within the viewport boundaries.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The problem persists as Vite is failing to load CSS codes enclosed within VUE components

My project is developed using Laravel, Inertia.js with Vue, and Vite for bundling the frontend assets. Everything seems to be working fine with the application, except when I try to access it from a subdirectory. In this scenario, Vite fails to load the C ...

Google Chrome does not support inlined sources when it comes to source maps

Greetings to all who venture across the vast expanse of the internet! I am currently delving into the realm of typescript-code and transcending it into javascript. With the utilization of both --inlineSourceMap and --inlineSources flags, I have observed t ...

Unable to communicate with Node.js websocket server from React client

I have the following server code: var http = require('http'), cors = require('cors'), connect = require('connect'), WebSocketServer = require('ws'); var DataController = function() { this.PORT = 809 ...

Steps to create a custom function that can manage numerous onclick actions to toggle the visibility of a specific field

I'm relatively new to coding and JavaScript. I'm working on a basic webpage that involves showing and hiding parts of sentences for language learning purposes. Is there a way to create a single function that can show and hide the sentence when a ...

Learning to retrieve specific properties from an event target in JavaScript

Here is the code snippet I am working with: <h1 msgId = "someId"> Some text </h1> And in my code.js file, I have the following function: document.addEventListener('click', function(e) { target = e.target; }, false); I am tryin ...

A TypeScript-enabled functional React component utilizing an onClick event handler for an anchor tag

I am working on a React component in TypeScript: interface Props { children: React.ReactNode; href: string; onClick?: (e: any) => void; } const Input: React.FC<Props> = ({ children, href, onClick }) => ( <a className="A" href={href ...

End-to-end testing using AngularJS Protractor is conducted to verify the message: 'Application has already been bootstrapped with this element'

Encountering an issue where my Protractor tests consistently fail with the following error message: UnknownError: Error Message => '[ng:btstrpd] App Already Bootstrapped with this Element '<html lang="en" data-ng-app="pmApp" class="js drag ...

Creating an engaging Uikit modal in Joomla to captivate your audience

I need help optimizing my modal setup. Currently, I have a modal that displays articles using an iframe, but there is some lag when switching between articles. Here is the JavaScript function I am using: function switchTitleMod1(title,id) { document.g ...

What could be causing the discrepancy in the model value when using checkboxes in AngularJS?

Something strange is happening with my code. I have a checkbox in my view that has a directive to display its value when it changes. Surprisingly, it works fine in Firefox, showing the correct values. However, in other browsers like Chrome, it shows the op ...

What is the best method for efficiently loading SVG icons on an HTML page without redundancy? / Is utilizing <use href> recommended?

My struggle with implementing icons in Angular While working on a new Angular project, I've encountered challenges with my current SVG-icon implementation method from a previous project (@ngneat/svg-icon). The process involves organizing SVG files in ...

Looking for jQuery developers to notify users that IE6 is not compatible

Currently, I am in the process of creating an app and have decided not to offer support for IE6. I want to ensure that users on IE6 understand this decision and do not assume the developers lack skills. I had hoped to find a JQUERY Plug-In that could easi ...

Three.js: sleek camera sliding gracefully around a central point

I have a challenge with my three.js project where I am rendering a cube in the center of two lines pointing to different directions. To interact with the scene, I am using OrbitControls along with some custom code (refer to the link below) to smoothly tran ...

Exploring the method of displaying a JSON 2D array through the utilization of getJSON

Is there a way to read 2D JSON data? An example of a JSON file is given below: [ { "name":"Menu1", "permission":"1", "link":"http://naver.com" }, { "name":"Menu2", "permission":"2", "link":"http://daum.net", ...

The functionality of two-way binding in a distinct controller is not functioning properly when integrated with angular-wizard

I've been working hard to integrate this amazing wizard controller into my project: However, I've hit a roadblock with two-way binding not functioning as expected outside of the <section> attribute: http://plnkr.co/edit/N2lFrBRmRqPkHhUBfn ...

What is the best way to adjust the height of an IFrame to match the size of its content?

I attempted to set the height of an IFrame to 100% (similar to setting a <div> to height:auto). I specified the height attribute in the <iframe> tag as 100% and also set the height in the style to 100%, but it doesn't appear to be functio ...

Is there a way to invoke a class method from the HTML that is specified within its constructor function?

class Welcome { constructor() { this.handlePress = this.handlePress.bind(this); this.htmlContent = `<a onclick="this.handlePress">Link</a>`; } handlePress(e) { console.log('planet'); } } The HTML structure appears ...

Using a combination of Internet Explorer, jQuery, Ajax, and XHTML can lead to HTML content being truncated after using either the .html

Trying to encapsulate this complex issue in a single sentence is proving to be quite challenging, so forgive me if I miss the mark. Recently, I launched a website after thorough testing on my local server with all major browsers, including IE8 (in IE8 sta ...

Unable to define attributes of a non-existent element (specifically 'innerHTML') within a Vanilla JavaScript component

Currently, I'm developing a Vanilla JS Component and encountering a challenge with utilizing the innerHTML() function to modify the text within a specific ID in the render() HTML code. The problem at hand is the Cannot set properties of null (setting ...

How can I update the source of an HTML video element seamlessly without causing any glitches?

I'm attempting to create a video call interface that plays videos generated based on user responses. I want the ability to seamlessly switch between the currently displayed video and the next generated video without the HTML collapsing and rebuilding ...

Is it possible for me to define TypeScript interfaces to be used in vanilla JavaScript projects within VSCode?

While using the MS VisualCode editor, I am attempting to implement type checking in my Javascript code. I want to maintain the flexibility of Javascript while also benefiting from type checking interfaces and data structures. Based on the vscode documenta ...