如何检测呈现的 HTML 内容是否为 blank/whitespace?

How to detect whether HTML content, when rendered, is blank/whitespace?

考虑如下代码:

<p>&nbsp;</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> &nbsp;</span></a>",
  "<a href='#'><span> &nbsp; </span></a>",
  "<a href='#'><span> &nbsp;</span></a> &nbsp;",
  "<p><a href='#'><span> &nbsp;</span></a> &nbsp;</p>",
  " <p><a href='#'><span> &nbsp;</span></a> &nbsp;</p> &nbsp; <p></p>",
  "<p>\n&nbsp;\n</p><ul><li></li></ul>"
 ],
 testStringsNo = [
  "<a href='#'><span> &nbsp;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]));
}