18

无论如何使用带有 Firefox 的 querySelector() 或 querySelectorAll() 函数的伪选择器来检测可见性?特别是我希望能够做这样的事情:

elem.querySelector('#list .list-item:visible');
elem.querySelector('#section .sub-section:visible .title');

无需担心浏览器不一致或其他实现,只需 Firefox。谢谢!

编辑: Visible 由display not nonevisibility not being hidden定义。

4

6 回答 6

21

由于 :visible 伪选择器没有原生实现,我决定使用 CSS 类来隐藏和显示我的元素,因此只需检查类名而不是可见性。这是我的选择器现在的样子:

elem.querySelector('#list .list-item:not(.hidden)');

现在在 2016 年,我们还可以使用隐藏的 html5 属性,所以这个选择器也可以工作:

elem.querySelector('#list .list-item:not([hidden])');
于 2012-11-14T23:19:15.083 回答
12

不,没有。CSS 规范没有定义:visible(或相关的)选择器,AFAIK Firefox 没有实现非标准的伪选择器。

如果您想自己实现它,请注意 jQuery 如何实现其:visible选择器:

在 jQuery 1.3.1(和更早版本)中,如果元素的 CSS“显示”不是“无”,它的 CSS“可见性”不是“隐藏”,并且它的类型(如果是输入)不是“隐藏”,则元素是可见的”。在 jQuery 1.3.2 中,如果浏览器报告的 offsetWidth 或 offsetHeight 大于 0,则元素可见。

来源:http ://docs.jquery.com/Release:jQuery_1.3.2#:visible.2F:hidden_​​Overhauled

于 2012-11-14T22:46:58.040 回答
11

display:none用于查找与 CSS 选择器不等价:visible的元素

:not([style='display:none'])

visibility:hidden如果需要,您可以对然后链接选择器执行相同的:not()操作。

这是一个小提琴

编辑:注意空格和其他标点符号。如果您稍后使用 JQuery 和 操作这些元素hide(),并且需要调用相同的函数,那么您将需要链接:not([style="display: none;"])到您的 CSS 选择器。

于 2019-01-18T19:07:13.587 回答
7

使用纯 javascript,您还可以轻松模拟 jQuery 行为,将您的 querySelector 结果转换为数组,并对其进行过滤:

Array.prototype.slice.call(document.querySelectorAll('your selector'))

这将创建一个包含选择器结果的普通数组,您可以将其过滤为:

.filter(function (item,index) { return item.style.display!="none" } );

甚至是其余的 jquery 条件(item.style.visibility != "hidden" && item.style.opacity > 0 && ...)。

作为一个班轮:

Array.prototype.slice.call(document.querySelectorAll('your selector')).filter(function (item,index) { return item.style.display!="none" } );
于 2017-10-18T10:52:06.313 回答
2

检查元素是否可见,支持所有主流浏览器:

jQuery:

$('.list-item').is(':visible');

香草JS:

function isVisible(elem) {return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0; }
于 2016-04-18T17:07:29.413 回答
0

您可以使用该offsetParent值来确定元素是否可见。

let parent = document.getElementById('parent');
let allSubChildren = parent.querySelectorAll('.sub-children');

let visibleChildren = Array.prototype.slice.call(allSubChildren).filter(function (item, index) {
    console.log('Element "' + item.textContent + '" is ' + (item.offsetParent !== null ? 'visible' : 'hidden'));
    return item.offsetParent !== null;
  }
);

console.log(visibleChildren);
.none {
  display: none;
}

.hidden {
  visibility: hidden;
}
<p><b>item.offsetParent</b> returns <b>null</b> if the element or any parent is not displayed.</p>
<em>Check the console</em>

<div id="parent">
  <div class="children">
    <div class="sub-children">visible</div>
  </div>
  <div class="children hidden">
    <div class="sub-children">visibility hidden doesn't work</div>
  </div>
  <div class="children none">
    <div class="sub-children">display none</div>
  </div>
  <div class="children">
    <div class="sub-children">also visible</div>
  </div>
  <div class="children">
    <div class="sub-children none">also display none</div>
  </div>
</div>

<div id="result">

</div>

于 2020-04-17T07:40:47.943 回答