css 查找元素或其任何祖先元素是否具有显示的执行方式:无

zhte4eai  于 2022-12-20  发布在  其他
关注(0)|答案(3)|浏览(134)

我需要找到一种性能非常好的方法来确定定制元素或其任何父元素是否具有display: none;
第一种方法:

checkVisible() {
  let parentNodes = [];
  let el = this;
  while (!!(el = el.parentNode)) {
    parentNodes.push(el);
  }
  return [this, ...parentNodes].some(el => getComputedStyle(el).display === 'none') 
}

还有比这更快的吗?这是一个安全的方法吗?
我需要这个的原因是:我们有一个<data-table>自定义元素(本地web组件),它在connectedCallback()中执行了非常繁重的任务。我们有一个应用程序,在一个页面中有20-30个这样的自定义元素,这导致IE 11需要大约15秒才能呈现页面。
我需要延迟那些<data-table>组件的初始化,这些组件最初甚至是不可见的,因此我需要一种方法来测试connectedCallback()内部的元素是否可见(如果它位于最初未显示的18个选项卡中的一个,则不可见)。

lc8prwob

lc8prwob1#

查看元素或其父元素是否具有display:none的最简单方法是使用el.offsetParent

const p1 = document.getElementById('parent1');
const p2 = document.getElementById('parent2');
const c1 = document.getElementById('child1');
const c2 = document.getElementById('child2');
const btn = document.getElementById('btn');
const output = document.getElementById('output');

function renderVisibility() {
  const p1state = isElementVisible(p1) ? 'is visible' : 'is not visible';
  const p2state = isElementVisible(p2) ? 'is visible' : 'is not visible';
  const c1state = isElementVisible(c1) ? 'is visible' : 'is not visible';
  const c2state = isElementVisible(c2) ? 'is visible' : 'is not visible';
  
  output.innerHTML = `Parent 1 ${p1state}<br>Parent 2 ${p2state}<br/>Child 1 ${c1state}<br/>Child 2 ${c2state}`;
}

function isElementVisible(el) {
  return !!el.offsetParent;
}

function toggle() {
  p1.style.display = (p1.style.display ? '' : 'none');
  p2.style.display = (p2.style.display ? '' : 'none');
  renderVisibility();
}

btn.addEventListener('click', toggle),
renderVisibility();
<div id="parent1" style="display:none">
  <div id="child1">child 1</div>
</div>
<div id="parent2">
  <div id="child2">second child</div>
</div>
<button id="btn">Toggle</button>
<hr>
<div id="output"></div>

这段代码将el.offsetParent转换为一个布尔值,表示元素是否显示。
这仅适用于display:none

dnph8jn4

dnph8jn42#

不确定性能如何,但至少应该比您的方法快:

HTMLElement.prototype.isInvisible = function() {
  if (this.style.display == 'none') return true;
  if (getComputedStyle(this).display === 'none') return true;
  if (this.parentNode.isInvisible) return this.parentNode.isInvisible();
  return false;
};
e4eetjau

e4eetjau3#

对于满足以下条件的纯函数:

  • 当且仅当元素本身及其任何父元素(直至文档本身)都没有style display === 'none'时,才返回TRUE
  • 当且仅当元素本身或任何父元素(直到文档本身)具有style display === 'none'时,返回FALSE

可以定义以下函数,然后在要验证的元素上调用该函数:

function isVisible(element) {
    // Start with the element itself and move up the DOM tree
    for (let el = element; el && el !== document; el = el.parentNode) {
        // If current element has display property 'none', return false
        if (getComputedStyle(el).display === "none") {
            return false;
        }
    }
    // Neither element itself nor any parents have display 'none', so return true
    return true;
}

相关问题