如何检测呈现的 HTML 内容是否为 blank/whitespace?
How to detect whether HTML content, when rendered, is blank/whitespace?
考虑如下代码:
<p> </p><!-- comment -->
<span></span><br />
<div><span class="foo"></span></div>
在浏览器上会有效地呈现为一段空白。
我想知道,鉴于该标记或类似标记,是否有一种直接的、编程的方法来检测这段代码去除空格的最终结果是一个空字符串。
此处的实现是 JavaScript,但我也对更通用的(与语言无关的)解决方案感兴趣,如果存在的话。
请注意,仅仅剥离标签并查看是否有任何文本残留并不是真正的解决方法,因为有很多标签最终会渲染可见内容(例如 img、hr 等)。
这是我想出的答案。它使用一个标签白名单,无论是否有内容,这些标签都假定在页面上呈现——所有其他标签都假定只有在它们有实际文本内容时才会呈现。一旦你有了它,实际上解决方案相当简单——它依赖于 innerText
属性自动去除所有标签这一事实。
此解决方案还会忽略基于 CSS 呈现的元素(例如,具有背景颜色的块或为 :after
或 :before
伪元素设置内容的块)但幸运的是这与我的用例无关。
function htmlIsWhitespace(input) {
var visible = [
'img','iframe','object','hr',
'audio', 'video',
'form', 'button', 'input', 'select', 'textarea'
],
container = document.createElement('div');
container.innerHTML = input;
return !(container.innerText.trim().length > 0 || container.querySelector(visible.join(',')));
}
// And the tests (I believe these are comprehensive):
var testStringsYes = [
"",
"<a href='#'></a>",
"<a href='#'><span></span></a>",
"<a href='#'><span> <!-- comment --></span></a>",
"<a href='#'><span> </span></a>",
"<a href='#'><span> </span></a>",
"<a href='#'><span> </span></a> ",
"<p><a href='#'><span> </span></a> </p>",
" <p><a href='#'><span> </span></a> </p> <p></p>",
"<p>\n \n</p><ul><li></li></ul>"
],
testStringsNo = [
"<a href='#'><span> hi</span></a>",
"<img src='#foo'>",
"<hr />",
"<div><object /></div>",
"<div><iframe /></div>",
"<div><object /></div>",
"<div><!-- hi -->bye</div>",
"<div><!-- what --><audio></audio></div>",
"<div><!-- what --><video></video></div>",
'<form><!-- empty --></form>',
'<input type="text">',
'<select name="foo"><option>1</option></select>',
'<textarea>',
'<input type="text">',
'<form><input type="button"></form>',
'<button />',
'<button>Push</button>',
"yo"
];
for(var yy=0, yl=testStringsYes.length; yy < yl; yy += 1) {
console.debug("Testing", testStringsYes[yy]);
console.assert(htmlIsWhitespace(testStringsYes[yy]));
}
for(var nn=0, nl=testStringsNo.length; nn < nl; nn += 1) {
console.debug("Testing", testStringsNo[nn]);
console.assert(!htmlIsWhitespace(testStringsNo[nn]));
}
考虑如下代码:
<p> </p><!-- comment -->
<span></span><br />
<div><span class="foo"></span></div>
在浏览器上会有效地呈现为一段空白。
我想知道,鉴于该标记或类似标记,是否有一种直接的、编程的方法来检测这段代码去除空格的最终结果是一个空字符串。
此处的实现是 JavaScript,但我也对更通用的(与语言无关的)解决方案感兴趣,如果存在的话。
请注意,仅仅剥离标签并查看是否有任何文本残留并不是真正的解决方法,因为有很多标签最终会渲染可见内容(例如 img、hr 等)。
这是我想出的答案。它使用一个标签白名单,无论是否有内容,这些标签都假定在页面上呈现——所有其他标签都假定只有在它们有实际文本内容时才会呈现。一旦你有了它,实际上解决方案相当简单——它依赖于 innerText
属性自动去除所有标签这一事实。
此解决方案还会忽略基于 CSS 呈现的元素(例如,具有背景颜色的块或为 :after
或 :before
伪元素设置内容的块)但幸运的是这与我的用例无关。
function htmlIsWhitespace(input) {
var visible = [
'img','iframe','object','hr',
'audio', 'video',
'form', 'button', 'input', 'select', 'textarea'
],
container = document.createElement('div');
container.innerHTML = input;
return !(container.innerText.trim().length > 0 || container.querySelector(visible.join(',')));
}
// And the tests (I believe these are comprehensive):
var testStringsYes = [
"",
"<a href='#'></a>",
"<a href='#'><span></span></a>",
"<a href='#'><span> <!-- comment --></span></a>",
"<a href='#'><span> </span></a>",
"<a href='#'><span> </span></a>",
"<a href='#'><span> </span></a> ",
"<p><a href='#'><span> </span></a> </p>",
" <p><a href='#'><span> </span></a> </p> <p></p>",
"<p>\n \n</p><ul><li></li></ul>"
],
testStringsNo = [
"<a href='#'><span> hi</span></a>",
"<img src='#foo'>",
"<hr />",
"<div><object /></div>",
"<div><iframe /></div>",
"<div><object /></div>",
"<div><!-- hi -->bye</div>",
"<div><!-- what --><audio></audio></div>",
"<div><!-- what --><video></video></div>",
'<form><!-- empty --></form>',
'<input type="text">',
'<select name="foo"><option>1</option></select>',
'<textarea>',
'<input type="text">',
'<form><input type="button"></form>',
'<button />',
'<button>Push</button>',
"yo"
];
for(var yy=0, yl=testStringsYes.length; yy < yl; yy += 1) {
console.debug("Testing", testStringsYes[yy]);
console.assert(htmlIsWhitespace(testStringsYes[yy]));
}
for(var nn=0, nl=testStringsNo.length; nn < nl; nn += 1) {
console.debug("Testing", testStringsNo[nn]);
console.assert(!htmlIsWhitespace(testStringsNo[nn]));
}