这是我想出的答案。它使用假设在页面上呈现的标记的白名单,无论它们是否具有内容 - 假定所有其他标记仅在具有实际文本内容时才呈现。一旦你有了这个,实际上解决方案相当简单 - 它依赖于innerText属性自动去除所有标签的事实。
该解决方案还忽略了渲染基于CSS元件(例如块具有背景颜色或其中的内容被设定为:after或:before伪元素),但幸运的是,这是不相关的我的使用情况。
function htmlIsWhitespace(input) {
\t var visible = [
\t \t \t 'img','iframe','object','hr',
\t \t \t 'audio', 'video',
\t \t \t 'form', 'button', 'input', 'select', 'textarea'
\t \t ],
\t \t container = document.createElement('div');
\t container.innerHTML = input;
\t return !(container.innerText.trim().length > 0 || container.querySelector(visible.join(',')));
}
// And the tests (I believe these are comprehensive):
var testStringsYes = [
\t \t "",
\t \t "
",\t \t "
\t \t "
\n \n
\t ],
\t testStringsNo = [
\t \t " hi",
\t \t "",
\t \t "
",
\t \t "
\t \t "
\t \t "
\t \t "
\t \t "
\t \t "
\t \t '
',\t \t '',
\t \t '1',
\t \t '',
\t \t '',
\t \t '
',\t \t '',
\t \t 'Push',
\t \t "yo"
\t ];
for(var yy=0, yl=testStringsYes.length; yy < yl; yy += 1) {
\t console.debug("Testing", testStringsYes[yy]);
\t console.assert(htmlIsWhitespace(testStringsYes[yy]));
}
for(var nn=0, nl=testStringsNo.length; nn < nl; nn += 1) {
\t console.debug("Testing", testStringsNo[nn]);
\t console.assert(!htmlIsWhitespace(testStringsNo[nn]));
}