找出元素或任何父元素是否具有显示的高性能方式:无

时间:2018-10-29 14:10:13

标签: javascript web-component custom-element native-web-component

我需要找到一种非常有效的方法来找出自定义元素或其任何父元素是否具有display: none;

第一种方法:

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

有什么比这更快的速度吗?这甚至是安全的方法吗?

我需要这个的原因:我们有一个<data-table>自定义元素(本机Web组件),它的connectedCallback()做得很繁重。我们有一个应用程序,在单个页面中有20-30个这些自定义元素,这导致IE 11大约需要15秒才能呈现页面。

我需要延迟最初甚至不可见的<data-table>组件的初始化,因此我需要一种方法在connectedCallback()内部测试该元素是否可见(如果可见,则不可以)在最初未显示的18个标签之一中。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

查看元素或其父元素是否具有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