如何让 .innerText 忽略不可见元素的不可见子元素?
How can I make `.innerText` ignore invisible children of an invisible element?
下面测试代码的结果:
div[0].innerText === "aaaaa zzzzz"
div[1].innerText === "aaaaainvisiblezzzzz"
如何强制 innerText
为 div[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 使其不可见,只能使用内联样式。除了 display: none
和 visibility: hidden
(例如,opacity: 0
,我想不出任何其他内联样式会使文本被排除在 innerText
之外t 这样做),所以排除那些并规范化非 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>
下面测试代码的结果:
div[0].innerText === "aaaaa zzzzz"
div[1].innerText === "aaaaainvisiblezzzzz"
如何强制 innerText
为 div[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 使其不可见,只能使用内联样式。除了 display: none
和 visibility: hidden
(例如,opacity: 0
,我想不出任何其他内联样式会使文本被排除在 innerText
之外t 这样做),所以排除那些并规范化非 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>