jQuery 補遺 - 取得文字節點
0 |
jQuery 寫了十幾年,自以為各種網頁 DOM 操作我都能信手拈來,今天硬是卡了一下,又一次體認到「沒學到的事還多著呢」
這回要處理的情境是將 div 裡多餘的 span 拆掉,將 span 內容在 div 展開到。例如:
<div>
<span>
First Line
<br />
Sencond Line
</span>
<br />
Third Line
</div>
要變成:
<div>
First Line
<br />
Sencond Line
<br />
Third Line
</div>
jQuery 要取出元素內容物,過去我只知道 .children(),再來就是 .html()。前者只取元素不含文字,在本例只會抓到 <br />
;取 HTML 的話,怎麼跟 div 的 HTML 串接會是好問題。
爬文學到我錯過的 jQuery 方法 - .contents(),概念與 .children() 相似,但差別在 .contents() 包含文字節點(Text Node)、註解(<!-- Comment -->
)... 等非元素項目。學會 .contents(),配上 .unwrap(),手到擒來:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Unwrap SPAN</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div>
<span>
First Line
<br />
Sencond Line
</span>
<br />
Third Line
</div>
<button type="button">Unwrap SPAN</button>
<script>
$('button').click(function () {
$('span').contents().unwrap();
});
</script>
</body>
</html>
用一個小範例結束這回合。程式先用原生 API .childNodes 取得包含文字節點的所有子節點,由 .nodeType 判別節點類別,元素為 1,文字為 3,註解為 8。順便練習 console.log('%c ...', 'color: orange') 改變顏色,console.table() 以表格方式顯示物件陣列。jQuery 部分對照了 .children() 與 .contents() 的區別,並用 .contents() 產生與 .childNodes 相同的結果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Text Node</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="d">
First Line
<br />
Second Line
<!-- Comment -->
</div>
<script>
//https://developer.mozilla.org/zh-TW/docs/Web/API/Node/nodeType
let nodeTypes = {
'1': 'ELEMENT_NODE',
'2': 'ATTRIBUTE_NODE',
'3': 'TEXT_NODE',
'4': 'CDATA_SECTION_NODE',
//'5': 'ENTITY_REFERENCE_NODE',
//'6': 'ENTITY_NODE',
'7': 'PROCESSING_INSTRUCTION_NODE',
'8': 'COMMENT_NODE',
'9': 'DOCUMENT_NODE',
'10': 'DOCUMENT_TYPE_NODE',
//'11': 'DOCUMENT_FRAGMENT_NODE',
//'12': 'NOTATION_NODE'
};
console.log('%c childNodes test', 'color: orange');
let d = document.getElementById("d");
let list = [];
d.childNodes.forEach(node => {
list.push({
type: nodeTypes[node.nodeType],
name: node.nodeName,
value: JSON.stringify(node.nodeValue)
});
});
console.table(list);
console.log('%c jQuery test', 'color: yellow');
jqd = $('#d');
console.log(`\$('#d').children().length = ${jqd.children().length}`);
console.log(`\$('#d').contents().length = ${jqd.contents().length}`);
list.length = 0;
jqd.contents().each(function (i, node) {
list.push({
type: nodeTypes[node.nodeType],
name: node.nodeName,
value: JSON.stringify(node.nodeValue)
});
});
console.table(list);
</script>
</body>
</html>
Comments
Be the first to post a comment