2017-06-21 108 views
3

考慮如下代碼:如何檢測HTML內容呈現時是空白/空格?

<p>&nbsp;</p><!-- comment --> 
<span></span><br /> 
<div><span class="foo"></span></div> 

其上的瀏覽器將有效地呈現爲空白的舒展。

我想知道,如果給定的或類似的標記,有一個直接的,編程方式來檢測這個代碼與空白剝離的最終結果是一個空字符串。

這裏的實現是JavaScript,但如果存在的話,我也對更一般的(語言不可知的)解決方案感興趣。

請注意,只刪除標籤並查看是否有任何文本仍然不是真正的解決方案,因爲有大量標籤最終呈現可見內容(例如img,hr等)。

+0

您可以使用CSS來呈現內容的頁面,只是在看標記可能不足以 – Musa

+0

使用DOM API,你有沒有考慮空白字符的列表,遞歸確認是否任何給定節點的唯一內容是空白文本(或節點是註釋等),如果是,則刪除該節點;如果您沒有節點,則全部爲空格。 - 請注意,這不會在白色背景上捕捉白色文字,例如... – deceze

回答

0

這是我想出的答案。它使用假設在頁面上呈現的標記的白名單,無論它們是否具有內容 - 假定所有其他標記僅在具有實際文本內容時才呈現。一旦你有了這個,實際上解決方案相當簡單 - 它依賴於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 "<a href='#'></a>", 
 
\t \t "<a href='#'><span></span></a>", 
 
\t \t "<a href='#'><span> <!-- comment --></span></a>", 
 
\t \t "<a href='#'><span> &nbsp;</span></a>", 
 
\t \t "<a href='#'><span> &nbsp; </span></a>", 
 
\t \t "<a href='#'><span> &nbsp;</span></a> &nbsp;", 
 
\t \t "<p><a href='#'><span> &nbsp;</span></a> &nbsp;</p>", 
 
\t \t " <p><a href='#'><span> &nbsp;</span></a> &nbsp;</p> &nbsp; <p></p>", 
 
\t \t "<p>\n&nbsp;\n</p><ul><li></li></ul>" 
 
\t ], 
 
\t testStringsNo = [ 
 
\t \t "<a href='#'><span> &nbsp;hi</span></a>", 
 
\t \t "<img src='#foo'>", 
 
\t \t "<hr />", 
 
\t \t "<div><object /></div>", 
 
\t \t "<div><iframe /></div>", 
 
\t \t "<div><object /></div>", 
 
\t \t "<div><!-- hi -->bye</div>", 
 
\t \t "<div><!-- what --><audio></audio></div>", 
 
\t \t "<div><!-- what --><video></video></div>", 
 
\t \t '<form><!-- empty --></form>', 
 
\t \t '<input type="text">', 
 
\t \t '<select name="foo"><option>1</option></select>', 
 
\t \t '<textarea>', 
 
\t \t '<input type="text">', 
 
\t \t '<form><input type="button"></form>', 
 
\t \t '<button />', 
 
\t \t '<button>Push</button>', 
 
\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])); 
 
}