javascript - 如何让 `.innerText` 忽略不可见元素的不可见子元素?

标签 javascript innertext

下面测试代码的结果:

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

我如何强制 innerTextdiv[1] 提供与为 div[0] 提供相同的结果?

我曾尝试将 div[1] 附加到一个临时文档,但由于该文档实际上并未显示,所以它没有帮助。只有将其附加到字面可见的文档中才有效。

测试代码

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 ,然后删除它,用户永远不会看到它:

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 使其不可见,只能使用内联样式。我想不出任何其他内联样式会使文本被排除在 innerText 之外。除了你的 display: nonevisibility: hidden (例如,opacity: 0 不会这样做),因此排除这些并规范化非 pre 的空白是微不足道的。元素:

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>),但如果您不想使用上面的第一个解决方案,您可以按照这个想法运行...

例子:

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>

关于javascript - 如何让 `.innerText` 忽略不可见元素的不可见子元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43060336/

相关文章:

javascript - jQuery 触发 DatePicker 更改事件

javascript - 在 hta 文件中使用 javascript

javascript - 如何通过innerText获取元素

javascript - 如果 div innerText 改变触发 JavaScript 事件

javascript - 在 CK Editor 中访问选项卡数据

javascript - 用于匹配有效 JavaScript 命名空间的正则表达式

javascript - 在加载@font-face-font 之前如何等待第一次 Canvas 重绘?

css - 为什么 textContent 不会触发重排

javascript - 在函数的 for 循环内动态更改元素的内部文本

javascript - 我如何撤消子字符串(例如将文本返回到其正常长度)