19

I have elements like below

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

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

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

I have a web page where there is send Message buttons like above, in which only one button is visible at a time.Other two buttons are hidden via some javascript codes.So for example if 2nd button is visible , I should be able to get only that element.

So my code will be something like

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

In jquery the code is $(".one:visible"); , which works fine , But I need to know how to do this via pure javascript.

6
  • 3
    Other two buttons are hidden via some javascript codes how are they hidden exactly? Commented Jun 18, 2017 at 5:56
  • I dont know , I am trying this in developer console , in some one else website , where there are list of users profiles with dropdown , when I click drop down send message list appears Commented Jun 18, 2017 at 6:07
  • I dont know - well, that's possibly a problem Commented Jun 18, 2017 at 6:08
  • Its facebook.com , they have like 100 javascript codes Commented Jun 18, 2017 at 6:09
  • To see how the element is being hidden, go into the DOM inspector, search (Ctrl-F) for .one to find the elements with that class, then view their properties to see if it's display: none or something else. Commented Jun 18, 2017 at 6:44

6 Answers 6

14

Here's something you can use, pure Javascript:

// Get all elements on the page (change this to another DOM element if you want)
var all = document.getElementsByTagName("*");

for (var i = 0, max = all.length; i < max; i++) {
    if (isHidden(all[i]))
        // hidden
    else 
        // visible
}

function isHidden(el) {
    var style = window.getComputedStyle(el);
    return ((style.display === 'none') || (style.visibility === 'hidden'))
}
Sign up to request clarification or add additional context in comments.

6 Comments

Could also be visibility: hidden or some other mechanism.
jquery does not use visibility check for :visible
if height or width is zero, is the element technically visible?
@JaromandaX The OP was referring to visible which for my understadning stands for display of visibility. I can see your comments to the PO which is not 100% on what he needs, I'm keeping an eye.
I don't believe this will work in the case of the my-element element in <div style="display: none; "><div id="my-element">Hi Bob</div></div>, because the computed style on my-element will not be display: none, yet it will be hidden because it's parent has display: none.
|
10

I have something shorter:

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

Returns all elements with attribute display block set.

1 Comment

If you need older browser support I would recommend also using this Polyfill for Array.from and .filter: polyfill.io/v3/…. If you arent using something like babel to transpile your arrow functions then you'll need to get rid of the arrow function.
6

Use getBoundingClientRect. It will return height and width of zero if the element is not in the DOM, or is not displayed.

Note that this cannot be used to determine if an element is not visible due to visibility: hidden or opacity: 0. AFAIK this behavior is identical to the jQuery :visible "selector". Apparently jQuery uses offsetHeight and offsetWidth of zero to check for non-visibility.

This solution will also not check if the item is not visible due to being off the screen (although you could check that easily enough), or if the element is hidden behind some other element.

See also Detect if an element is visible (without using jquery)

Comments

3
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);
    }
}

First we get all the elements using document querySelectorAll. Then, we need to iterate over all the elements. To get the style, use getComputedStyle.

After that :visible check only for display and we do it the same way.

A more comprehensive approach:

function isVisible(el) {
        while (el) {
            if (el === document) {
                return true;
            }

            var $style = window.getComputedStyle(el, null);

            if (!el) {
                return false;
            } else if (!$style) {
                return false;
            } else if ($style.display === 'none') {
                return false;
            } else if ($style.visibility === 'hidden') {
                return false;
            } else if (+$style.opacity === 0) {
                return false;
            } else if (($style.display === 'block' || $style.display === 'inline-block') &&
                $style.height === '0px' && $style.overflow === 'hidden') {
                return false;
            } else {
                return $style.position === 'fixed' || isVisible(el.parentNode);
            }
        }
    }

This would check for any possible way an element could be visible in the dom to my knowledge minus the z-index cases.

7 Comments

But does this actually work? An element could have a computed display of "block", but yet be hidden due to an ancestor having a display of "none".
updated the answer with a more comprehensive, perhaps cherry-picking the conditions as per requirement would be great.
What is the purpose of the while (el)?
to check if el exists or not in the first place, any condition would otherwise be prone to undefined or null, just an added safe check
It's identical to, and should be, if (el).
|
3

If you're using the hidden attribute :

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

2 Comments

Hi, above does not fly with display: none.
@MatasVaitkevicius Nope, as stated, only with the hidden attribute
2

So all jQuery's :visible selector does is check the display property. If that's all you want, this is all you'd need.

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

However, this is lacking in many use cases. If you seek a more comprehensive solution, keep reading.

Both Element.getBoundingClientRect() and window.getComputedStyle() are useful for determining if the element is visible and in the viewport.

You can't use getBoundingRect() alone to determine the visibility, and while you could use getComputedStyle() solely, it's not the optimal solution in terms of performance.

Both of these functions used in conjunction with each other is the best option (around 22% faster than 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;
}

With a usage example of...

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

This ensures that the display is not set to "none", the visibility is "visible", the width and height are greater than 0, and the element is within the bounds of the viewport.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.