如何使.innerText忽略不可见元素的不可见子元素? [英] How can I make `.innerText` ignore invisible children of an invisible element?

查看:116
本文介绍了如何使.innerText忽略不可见元素的不可见子元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下测试代码的结果:

div[0].innerText === "aaaaa zzzzz"
div[1].innerText === "␤aaaaa␤invisible␤zzzzz␤"

如何强制innerTextdiv[1]赋予与div[0]相同的结果?

How can I force innerText to give the same result for div[1] as it gives for div[0]?

我尝试将div[1]附加到临时文档中,但是由于该文档并未真正显示,因此没有帮助.仅将其附加到字面上可见的文档中即可.

I’ve tried to append div[1] to a temporary document but, since the document wasn’t actually displayed, it didn’t help. Only appending it to a literally visible document works.

var div = [];
div[0] = document.getElementById("visible");
div[1] = div[0].cloneNode(true);

show(0);
show(1);

function show(i) {
    document.getElementById("output").innerHTML += 
      "<p>div[" + i + "].innerText === <code>" + 
      div[i].innerText.replace(/\n/g, "␤") + "</code></p>";
}

#visible {display: block; font-family: sans-serif; font-size: larger; color: red;}
code {background-color: lightgray; padding: 0 .318em;}

<div id="visible">
<span style="display: inline">aaaaa</span>
<span style="display: none">invisible</span>
<span style="display: inline">zzzzz</span>
</div>

<div id="output"></p>

推荐答案

仅将其附加到用户真正可见的文档中即可.

Only appending it to a document literally visible to the user works.

但是用户不必一定要看到它. :-)如果添加它,请抓住innerText,然后将其删除,用户将永远不会看到它:

But the user doesn't necessarily have to see that. :-) If you append it, grab innerText, and then remove it, the user will never see it:

var div = [];
div[0] = document.getElementById("visible");
div[1] = div[0].cloneNode(true);

show(0);
document.body.appendChild(div[1]);  // *****
show(1);
document.body.removeChild(div[1]);  // *****

function show(i) {
    document.getElementById("output").innerHTML += 
      "<p>div[" + i + "].innerText === <code>" + 
      div[i].innerText.replace(/\n/g, "␤") + "</code></p>";
}

#visible {display: block; font-family: sans-serif; font-size: larger; color: red;}
code {background-color: lightgray; padding: 0 .318em;}

<div id="visible">
<span style="display: inline">aaaaa</span>
<span style="display: none">invisible</span>
<span style="display: inline">zzzzz</span>
</div>

<div id="output"></p>

或者,由于该元素不在DOM中,因此CSS不能使它不可见,而只能是内联样式.除了您的display: nonevisibility: hidden(例如,opacity: 0不会这样做)之外,我想不出其他任何会使文本被排除在innerText外的内联样式,所以这很简单排除那些元素并标准化非pre元素的空格:

Alternately, since the element isn't in the DOM, it can't be made invisible by CSS, only inline styles. I can't think of any other inline style that would make the text get left out of innerText other than your display: none and visibility: hidden (opacity: 0, for instance, doesn't do it), so it's trivial to exclude those and normalize whitespace for non-pre elements:

function getInnerText(element) {
  var node, text = "";
  if (element.style.display.toLowerCase() !== "none" && element.style.visibility.toLowerCase() !== "hidden") {
    for (node = element.firstChild; node; node = node.nextSibling) {
      if (node.nodeType === 3) {
        text += node.nodeValue;
      } else if (node.nodeType === 1) {
        text += getInnerText(node);
      }
    }
  }
  // Normalize all whitespace if not "pre"
  if (element.tagName !== "PRE" && element.style.whiteSpace.toLowerCase().indexOf("pre") == -1) {
    text = text.replace(/\s+/g, ' ');
  }
  return text;
}

这很可能需要进行调整(我认为它不能正确处理<div>stuff<pre>big gap</pre></div>),但是如果您不想使用上面的第一个解决方案,则可以执行此操作...

That may well need tweaking (I don't think it handles <div>stuff<pre>big gap</pre></div> properly), but you can run with the idea if you don't want to use the first solution above...

示例:

var div = [];
div[0] = document.getElementById("visible");
div[1] = div[0].cloneNode(true);

show(0);
document.body.appendChild(div[1]);  // *****
show(1);
document.body.removeChild(div[1]);  // *****

function show(i) {
    document.getElementById("output").innerHTML += 
      "<p>div[" + i + "].innerText === <code>" + 
      getInnerText(div[i]).replace(/\n/g, "␤") + "</code></p>";
}

function getInnerText(element) {
  var node, text = "";
  if (element.style.display.toLowerCase() !== "none" && element.style.visibility.toLowerCase() !== "hidden") {
    for (node = element.firstChild; node; node = node.nextSibling) {
      if (node.nodeType === 3) {
        text += node.nodeValue;
      } else if (node.nodeType === 1) {
        text += getInnerText(node);
      }
    }
  }
  // Normalize all whitespace if not "pre"
  if (element.tagName !== "PRE" && element.style.whiteSpace.toLowerCase().indexOf("pre") == -1) {
    text = text.replace(/\s+/g, " ");
  }
  return text;
}

#visible {display: block; font-family: sans-serif; font-size: larger; color: red;}
code {background-color: lightgray; padding: 0 .318em;}

<div id="visible">
<span style="display: inline">aaaaa</span>
<span style="display: none">invisible</span>
<span style="display: inline">zzzzz</span>
</div>

<div id="output"></p>

这篇关于如何使.innerText忽略不可见元素的不可见子元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆