text節點無innerHTML這個屬性!!!
若是直接修改text節點的屬性(data,nodeValue,textContent),或者使用js原生的修改text節點的內容的方法都會將HTML的預留字符變成轉義字符直接顯示成文本了,解決方法有:javascript
replaceWith: function( value ) { var isFunc = jQuery.isFunction( value ); // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( !isFunc && typeof value !== "string" ) { value = jQuery( value ).not( this ).detach(); } return this.domManip( [ value ], true, function( elem ) { var next = this.nextSibling, parent = this.parentNode; if ( parent ) { jQuery( this ).remove(); parent.insertBefore( elem, next ); } }); },
例:將pre標籤中的回車替換爲<br>,空格替換爲&ebsp;,製表符替換成雙&ebsp;css
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> pre, code { font-family: "Menlo", monospace; -webkit-text-size-adjust: 100%; } code { line-height: 1em; } pre { border-left: solid 2px #ccc; padding-left: 18px; margin: 2em 0 2em -20px; } .html .string, .javascript .string, .javascript .regexp { color: #756bb1; } .html .tag, .css .tag, .javascript .keyword { color: #3182bd; } .comment { color: #636363; } .html .doctype, .javascript .number { color: #31a354; } .html .attr, .css .attr, .javascript .class, .javascript .special { color: #e6550d; } </style> </head> <body> <pre><code class="javascript hljs">d3.selectAll(<span class="string">"circle"</span>).transition() .duration(<span class="number">750</span>) .delay(<span class="function"><span class="keyword">function</span>(<span class="params">d, i</span>) </span>{ <span class="keyword">return</span> i * <span class="number">10</span>; }) .attr(<span class="string">"r"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{ <span class="keyword">return</span> <span class="built_in">Math</span>.sqrt(d * scale); });</code></pre> <button onclick="pre_replace()">Replace all line breaks,blanks and tabs.</button> <p>innerHTML of pre: </p> <p id="html-of-pre"></p> <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script> <script> //引入jquery僅僅爲了使用jquery的replaceWith方法 'use strcat' var pre = document.querySelector('pre') var p = document.querySelector('#html-of-pre') p.innerText = pre.innerHTML /** 遞歸獲取子節點 1 Element 表明元素 2 Attr 表明屬性 3 Text 表明元素或屬性中的文本內容 4 CDATASection 表明文檔中的 CDATA 部分(不會由解析器解析的文本) 5 EntityReference 表明實體引用 6 Entity 表明實體 7 ProcessingInstruction 表明處理指令 8 Comment 表明註釋 9 Document 表明整個文檔(DOM 樹的根節點) 10 DocumentType 向爲文檔定義的實體提供接口 11 DocumentFragment 表明輕量級的 Document 對象,可以容納文檔的某個部分 12 Notation 表明 DTD 中聲明的符號 */ var allChildNodes = function(node, type){ // 1.建立所有節點的數組 var allCN = []; // 2.遞歸獲取所有節點 var getAllChildNodes = function(node, type, allCN){ // 獲取當前元素全部的子節點nodes var nodes = node.childNodes; // 獲取nodes的子節點 for (var i = 0; i < nodes.length; i++) { var child = nodes[i]; // 判斷是否爲指定類型節點 if(child.nodeType == type){ allCN.push(child); } getAllChildNodes(child, type, allCN); } } getAllChildNodes(node, type, allCN); // 3.返回所有節點的數組 return allCN; } var pre_replace = function(){ var keys = Object.keys || function(obj) { obj = Object(obj) var arr = [] for (var a in obj) arr.push(a) return arr } var replace_map = { '\n': "<br/>", ' ': " ", '\t': "  " } var allTextNodes = allChildNodes(pre, 3); /* text節點無innerHTML這個屬性!!! 若是直接修改text節點的屬性(data,nodeValue,textContent),或者使用js原生的修改text節點的內容的方法都會將HTML的預留字符變成轉義字符直接顯示成文本了,解決方法有: 1. 使用正則表達式找出pre的innerHTML字符串中的所有text節點的字符串進行修改 2. 給text外面包裹一個標籤,改包裹標籤的innerHTML,把包裹標籤的內容移動到外面,刪除包裹標籤 3. 使用jquery的replaceWith方法,這個就很是嚴謹了 replaceWith: function( value ) { var isFunc = jQuery.isFunction( value ); // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( !isFunc && typeof value !== "string" ) { value = jQuery( value ).not( this ).detach(); } return this.domManip( [ value ], true, function( elem ) { var next = this.nextSibling, parent = this.parentNode; if ( parent ) { jQuery( this ).remove(); parent.insertBefore( elem, next ); } }); }, */ allTextNodes.forEach(function(textNode){ $(textNode).replaceWith(()=>{ return textNode.data.replace(RegExp('[' + keys(replace_map).join('') + ']', 'g'), function(match){ // console.log(match, replace_map[match]) return replace_map[match] }) }) }); p.innerText = pre.innerHTML } </script> </body> </html>