Read the article on the Internet, readers will often want to their own feelings in a paragraph to write something, it’s a pity that most of the reading web site does not provide this functionality, the reader is often only the text copied to the local or online editor to edit comments, if you want to review these comments elsewhere after also must be installed to local or network login (notes) cloud editor. So I decided to write a simple gadget to try to solve this problem.

I. Usage:

Open the tool in Chrome

Click the “select a text file” choose TXT file, or directly to the plain text pasted into the text box, click ok with a green background show the text content, namely the double-click green body paragraphs popup yellow comments in the following paragraphs, double-click the annotation paragraphs can edit comment content (text not edit), editor click elsewhere, cancel, Double-click the green text paragraph again to hide the comment.

Click export HTML content of the text and comments can be saved as an HTML document, use Chrome to open the HTML documents that can view has been input text and annotation, the export of the HTML document also has all features of this tool, the user can continue to edit the comment, or completely replace loading the new text, After editing, you can export it as a new HTML document.

Two, writing method:

1, first spell out an HTML structure:

1 <! DOCTYPE HTML > 2 < HTML lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title> </title> 6 <style> 7 /* body{/ 8 body: 0; padding: 0; border: 0; text-align: center; overflow: hidden; width: 100%; 9 height: 100%; position: fixed; font-family: verdana,arial,sans-serif; touch-action: none; 10 -ms-touch-action: none; font-size: 12px; min-width: 600px; } 11 ul { list-style: none; margin: 0; padding: 0; } 12 li{ list-style: none; margin: 0; padding: 0; } 13 ul li { float: left; } 14 button{ cursor: pointer; height: 23px; } 15 a:link{ text-decoration: none; } 16 17 #div_top span,input,button,textarea{margin-left: 20px; float: left; } 18 .p_h1{font-size: 24px; font-weight: bolder; background-color: darkseagreen} 19 .p_text{font-size: 20px; font-weight: normal; text-align: left; background-color: darkseagreen} 20 21 .div_section{position:relative} 22 .p_a1{font-size: 20px; font-weight: normal; text-align: left; background-color: beige; margin-left: 60px; margin-right: 60px; 23. min-height: 80px; display: block; word-break: break-all; overflow-wrap: break-word; white-space: pre-wrap} 24 .p_a2{font-size: 20px; font-weight: normal; text-align: left; background-color: beige; margin-left:120px} 25 </style> 26 </head> 27 <body> 28 <div id="div_allbase" style="top:0px; bottom:0px; width:100%; height: 100%; position:relative; overflow-x: hidden; overflow-y: scroll 29 "> 30 <div id="div_top" style="top:0px; left:0px; width:100%; height: 30px; position:absolute;" > 31 <span style="margin-left: </span> 32 <input type="file" id="str_local" onchange="ShowStr()" style="margin-left: <span style="margin-left: 20px"> 33 <span style="margin-left: 20px"> 34 <textarea type="text" id="str_local2" style="word-break: break-all: break-all; overflow-wrap: break-word; white-space: pre-wrap; Font: url "></ url onclick="ExportHtml()"> url </ url > 37 </div> 38 <div id="div_main" style="top:30px; left:0px; width:100%; position:absolute;" > 39 40 </div> 41 </div> 42 </body>Copy the code

Div_top is the operation area above, and div_main is used to store text paragraphs and comment paragraphs. The text box uses the Textarea tag instead of the input tag, because the input tag automatically replaces multiple lines of text with a space, and the white-space: pre-wrap style tells the Textarea tag to keep the newline, or else the newline will be replaced.

2. Convert plain text to body paragraphs:

Var str_local= document.getelementbyid ("str_local"); var str_local= document.getelementbyid ("str_local"); 4 var file=str_local.files[0]; 5 var reader=new FileReader(); 6 reader.readAsText(file); 7 reader.onload=function(e) 8 { 9 var str=e.target.result; 10 loadArticle(str); 14 {15 var str_local= document.getelementbyid ("str_local2"); 14 {15 var str_local= document.getelementbyid ("str_local2"); 16 var str=str_local.value; 17 loadArticle(str); 18 } 19 var currentSectionid=null; 20 function loadArticle(str) 21 { 22 var div_main=document.getElementById("div_main"); 23 div_main.innerHTML=""; 24 var arr_section=str.split("\r\n"); 25 var len=arr_section.length; 27 {28 arr_section=str.split("\n"); 26 if(len==1)// If (arr_section=str.split("\n"); 29 } 30 len=arr_section.length; 31 var count_p=0; Var arr_p=[]; var arr_p=[]; 33 for(var i=0; i<len; i++) 34 { 35 var section=arr_section[i]; 36 if(section.length>0) 37 { 38 let div_section=document.createElement("div"); 39 div_section.className="div_section"; Div_section. id="div_section_"+count_p; 41 42 let p=document.createElement("p"); If (count_p==0) {45 p.className="p_h1"; 46 } 47 else 48 { 49 p.className="p_text"; 50 } 51 p.innerHTML=" "+section; 52 p.id="p_section_"+count_p; 53 54 p.ondblclick=function() 55 { 56 addAnnotate(div_section.id); 57 } 58 count_p++; 59 div_section.appendChild(p); 60 div_main.appendChild(div_section); 61} 62} 63}Copy the code

 

The code is not complicated. The text is segmented according to \r\n (used when reading from a text box), and each section generates a corresponding HTML document to be inserted into the DOM. Each “section” has a unique DOM ID. What hasn’t been debugged yet is how to keep the four Spaces in front of each paragraph when exporting and importing HTML, which the browser will automatically remove.

Note that when setting event responses for batch-created tags, use let variables instead of var variables, otherwise all event responses defined in the same loop will target the last tag of the loop operation.

3. Double-click the text paragraph to expand the comment paragraph:

1 function addAnnotate(id) 2 { 3 var div_section=document.getElementById(id); 4 currentSectionid=id; Var children=div_section.childNodes; 6 var len=children.length; {7 let p_a1=document.createElement("p"); 10 p_a1.className="p_a1"; P_a1. Ondblclick =function(){openEdit(p_a1)}; 13 p_a1.onblur=function(){closeEdit(p_a1)}; Div_section. appendChild(p_a1) 15} 16 else 17 {18 if(children[1].style.display=="none")// If the current state is hidden  19 { 20 for(var i=1; i<len; i++) 21 { 22 children[i].style.display="block"; 23} 24} 25 else 26 {27 for(var I =1; i<len; i++) 28 { 29 var child=children[i]; 30 child.style.display="none"; If (child.className=="p_a1") 32 {33 closeEdit(child); 34} 35} 36} 37} 38}Copy the code

Here, find the body paragraph div of the current action by sectionID and insert the blank comment paragraph.

4. Edit comments and close editing state:

1 function openEdit(p) 2 { 3 p.style.border="2px solid cornflowerblue"; 4 p.style.borderRadius="5px"; 5 p.contentEditable="true"; 6 } 7 function closeEdit(p) 8 { 9 p.style.border="0px"; 10 p.contentEditable="false"; 11 //Chrome's default editing mode inserts a div into p, which is used for line breaking, and a blank line break will also result in div!! 12 // But after reimporting the div, the browser will automatically draw the div outside of the p !!!! 13 // Multiple newlines are nested !!!! So simple substitution is not enough!! 14 p.innerHTML=p.innerHTML.replace(new RegExp(("<[^>]+>"),"gm"),"@"); / / if there are multiple XML tags of continuous 15 p.i nnerHTML = p.i nnerHTML. Replace (new RegExp (((@) + "")," gm "), "\ r \ n"); 16 //p.innerHTML=p.innerHTML.replace(new RegExp(("<[^>]+>"),"gm"),"\r\n"); 17 / / p.i nnerHTML = p.i nnerHTML. Replace (new RegExp ((" < / ^ /] [\ \ S] {1, 5} > "), "gm"), "\ r \ n"); 18 / / p.i nnerHTML = p.i nnerHTML. Replace (new RegExp ((" < / [\ \ S] {1, 6} > "), "gm"), ""); 19}Copy the code

The built-in ‘contentEditable’ property of the browser is used to edit the contents of the P tag. A disadvantage of this is that the browser inserts tags in various control formats without the user’s control as the tag is being edited, and the same HTML is automatically arranged in a different order when imported into the browser according to different rules. (Browser-like CSS debugging that is only expected to be used once at runtime?)

To solve this problem, I used regular expressions to clean up all the XML tags when I turned off the contentEditable state of the P tag, but this also caused a new problem — the XML tags (including the substitution symbol @) that the user wanted to write in the comments would also be cleaned up. I wonder if there is a better way to solve this problem.

5, export HTML document:

1 function ExportHtml() 2 { 3 var str=str_head+window.document.body.outerHTML+"</html>"; 5 var tmpa = document.createElement("a"); 5 var tmpa = document.createElement("a"); 9 var p_h1=document.getElementsByClassName("p_h1")[0]; 10 tmpa.download = (p_h1? p_h1.innerHTML:"test")+".html"; 11 tmpa. Href = url.createObjecturl (blob); // Download 12 tmpa.click() with temporary A tag; // After the export events need to be rebound, or use innHTML definition directly? 13 setTimeout(function () { 14 URL.revokeObjectURL(blob); // release stream 15}, 100); 16}Copy the code

Str_head contains the HTML header content, plus the body content and the HTML closing tag that are currently being edited to form an exported HTML document, which is then converted to a binary file stream and downloaded with a temporary A tag.

Note that events bound with.onxx are not exported with the HTML document; you can choose to rebind the event when opening the HTML, or write the event response directly into innerHTML using the innerHTML instead of the appendChild method when creating the tag

Rebind event when reopening the exported HTML document:

1 window.onload=function(){2 // Use innerHTML to define all dynamically generated tags. Var div_main= document.getelementById ("div_main"); 4 var arr_section=div_main.getElementsByClassName("div_section"); 5 var len=arr_section.length; 6 for(var i=0; i<len; i++) 7 { 8 let div_section=arr_section[i]; 9 var arr_p=div_section.getElementsByTagName("p"); 10 var len2=arr_p.length; 11 for(var j=0; j<len2; j++) 12 { 13 let p=arr_p[j]; 14 if(j==0) 15 { 16 p.ondblclick=function() 17 { 18 addAnnotate(div_section.id); 19 } 20 } 21 else 22 { 23 p.ondblclick=function(){openEdit(p)}; 24 p.onblur=function(){closeEdit(p)}; 25} 26} 27} 28}Copy the code

This completes the article comment editor widget. Here is the complete code, which can be used by copying and pasting it into a blank.html file.

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>实用版,处理事件问题</title>
  6     <style>
  7         /*通用属性*/
  8         body{    margin: 0;    padding: 0;    border: 0;    text-align: center;    overflow: hidden;width: 100%;
  9             height: 100%;position: fixed;    font-family: verdana,arial,sans-serif;    touch-action: none;
 10             -ms-touch-action: none;font-size: 12px;min-width: 600px;}
 11         ul {    list-style: none;    margin: 0;    padding: 0;}
 12         li{    list-style: none;    margin: 0;    padding: 0;}
 13         ul li {    float: left;}
 14         button{    cursor: pointer;    height: 23px;}
 15         a:link{    text-decoration: none;}
 16 
 17         #div_top span,input,button,textarea{margin-left: 20px;float: left;}
 18         .p_h1{font-size: 24px;font-weight: bolder;background-color: darkseagreen}
 19         .p_text{font-size: 20px;font-weight: normal;text-align: left;background-color: darkseagreen}
 20 
 21         .div_section{position:relative}
 22         .p_a1{font-size: 20px;font-weight: normal;text-align: left;background-color: beige;margin-left: 60px;margin-right: 60px;
 23         ;min-height: 80px;display: block;word-break: break-all;overflow-wrap: break-word;white-space: pre-wrap}
 24         .p_a2{font-size: 20px;font-weight: normal;text-align: left;background-color: beige;margin-left:120px}
 25     </style>
 26 </head>
 27 <body>
 28     <div id="div_allbase" style="top:0px;bottom:0px;width:100%;height: 100%;position:relative;overflow-x: hidden;overflow-y: scroll
 29         ">
 30         <div id="div_top" style="top:0px;left:0px;width:100%;height: 30px;position:absolute;">
 31             <span style="margin-left: 20px">选择文本文件</span>
 32             <input type="file" id="str_local" onchange="ShowStr()" style="margin-left: 20px">
 33             <span style="margin-left: 20px">粘贴文本</span>
 34             <textarea type="text" id="str_local2" style="word-break: break-all;overflow-wrap: break-word;white-space: pre-wrap;height:40px"></textarea>
 35             <button onclick="ShowStr2()">确定</button>
 36             <button onclick="ExportHtml()">导出Html</button>
 37         </div>
 38         <div id="div_main" style="top:30px;left:0px;width:100%;position:absolute;">
 39 
 40         </div>
 41     </div>
 42 </body>
 43 <script>
 44 
 45     window.onload=function(){
 46         //处理导出html的事件有两种思路,一是使用innerHTML定义所有动态生成的标签,二是在每次打开网页时重新绑定事件
 47         var div_main=document.getElementById("div_main");
 48         var arr_section=div_main.getElementsByClassName("div_section");
 49         var len=arr_section.length;
 50         for(var i=0;i<len;i++)
 51         {
 52             let div_section=arr_section[i];
 53             var arr_p=div_section.getElementsByTagName("p");
 54             var len2=arr_p.length;
 55             for(var j=0;j<len2;j++)
 56             {
 57                 let p=arr_p[j];
 58                 if(j==0)
 59                 {
 60                     p.ondblclick=function()
 61                     {
 62                         addAnnotate(div_section.id);
 63                     }
 64                 }
 65                 else
 66                 {
 67                     p.ondblclick=function(){openEdit(p)};
 68                     p.onblur=function(){closeEdit(p)};
 69                 }
 70             }
 71         }
 72     }
 73     function ShowStr()
 74     {
 75         var str_local=document.getElementById("str_local");
 76         var file=str_local.files[0];
 77         var reader=new FileReader();
 78         reader.readAsText(file);
 79         reader.onload=function(e)
 80         {
 81             var str=e.target.result;
 82             loadArticle(str);
 83         }
 84     }
 85     function ShowStr2()
 86     {
 87         var str_local=document.getElementById("str_local2");
 88         var str=str_local.value;
 89         loadArticle(str);
 90     }
 91     var currentSectionid=null;
 92     function loadArticle(str)
 93     {
 94         var div_main=document.getElementById("div_main");
 95         div_main.innerHTML="";
 96         var arr_section=str.split("\r\n");
 97         var len=arr_section.length;
 98         if(len==1)
 99         {
100             arr_section=str.split("\n");
101         }
102         len=arr_section.length;
103         var count_p=0;//包含主标题在内一共分成几段
104         var arr_p=[];
105         for(var i=0;i<len;i++)
106         {
107             var section=arr_section[i];
108             if(section.length>0)
109             {
110                 let div_section=document.createElement("div");
111                 div_section.className="div_section";//这样可以更方便的在段内插入元素
112                 div_section.id="div_section_"+count_p;
113 
114                 let p=document.createElement("p");
115                 if(count_p==0)//标题段
116                 {
117                     p.className="p_h1";
118                 }
119                 else
120                 {
121                     p.className="p_text";
122                 }
123                 p.innerHTML="    "+section;
124                 p.id="p_section_"+count_p;
125 
126                 p.ondblclick=function()
127                 {
128                     addAnnotate(div_section.id);
129                 }
130                 count_p++;
131                 div_section.appendChild(p);
132                 div_main.appendChild(div_section);
133             }
134         }
135     }
136     function addAnnotate(id)
137     {
138         var div_section=document.getElementById(id);
139         currentSectionid=id;
140         var children=div_section.childNodes;
141         var len=children.length;
142         if(len==1)//此时还没有第一级注释
143         {
144             let p_a1=document.createElement("p");
145             p_a1.className="p_a1";
146             //点击第一级注释,进行编辑
147             p_a1.ondblclick=function(){openEdit(p_a1)};
148             p_a1.onblur=function(){closeEdit(p_a1)};
149             div_section.appendChild(p_a1)
150         }
151         else
152         {
153             if(children[1].style.display=="none")//如果当前是隐藏状态
154             {
155                 for(var i=1;i<len;i++)
156                 {
157                     children[i].style.display="block";
158                 }
159             }
160             else
161             {
162                 for(var i=1;i<len;i++)
163                 {
164                     var child=children[i];
165                     child.style.display="none";
166                     if(child.className=="p_a1")
167                     {
168                         closeEdit(child);
169                     }
170                 }
171             }
172         }
173     }
174     function openEdit(p)
175     {
176         p.style.border="2px solid cornflowerblue";
177         p.style.borderRadius="5px";
178         p.contentEditable="true";
179     }
180     function closeEdit(p)
181     {
182         p.style.border="0px";
183         p.contentEditable="false";
184         //Chrome的默认编辑模式会在p内插入一个div,这个div是用来分行的,空白的换行也会导致div!!
185         // 但在重新导入之后(在取innerHTML导出时尚正常)浏览器会自动把这个div绘制在p的外面!!!!
186         //多次换行是嵌套的!!!!所以简单的替换还不行!!
187         p.innerHTML=p.innerHTML.replace(new RegExp(("<[^>]+>"),"gm"),"@");
188         p.innerHTML=p.innerHTML.replace(new RegExp(("[@]+"),"gm"),"\r\n");
189         //p.innerHTML=p.innerHTML.replace(new RegExp(("<[^>]+>"),"gm"),"\r\n");
190         //p.innerHTML=p.innerHTML.replace(new RegExp(("<[^/][\\S]{1,5}>"),"gm"),"\r\n");
191         //p.innerHTML=p.innerHTML.replace(new RegExp(("</[\\S]{1,6}>"),"gm"),"");
192     }
193 
194     function ExportHtml()
195     {
196         var str=str_head+window.document.body.outerHTML+"</html>";
197         var blob=new Blob([str],{
198             type: "text/plain"
199         })
200 
201         var tmpa = document.createElement("a");
202         var p_h1=document.getElementsByClassName("p_h1")[0];
203         tmpa.download = (p_h1?p_h1.innerHTML:"test")+".html";
204         tmpa.href = URL.createObjectURL(blob);
205         tmpa.click();//导出后事件需要重新绑定,或者直接使用innHTML定义?
206         setTimeout(function () {
207             URL.revokeObjectURL(blob);
208         }, 100);
209     }
210 
211     var str_head="<!DOCTYPE html>\n" +
212         "<html lang=\"en\">\n" +
213         "<head>\n" +
214         "    <meta charset=\"UTF-8\">\n" +
215         "    <title>实用版</title>\n" +
216         "    <style>\n" +
217         "        /*通用属性*/\n" +
218         "        body{    margin: 0;    padding: 0;    border: 0;    text-align: center;    overflow: hidden;width: 100%;\n" +
219         "            height: 100%;position: fixed;    font-family: verdana,arial,sans-serif;    touch-action: none;\n" +
220         "            -ms-touch-action: none;font-size: 12px;min-width: 600px;}\n" +
221         "        ul {    list-style: none;    margin: 0;    padding: 0;}\n" +
222         "        li{    list-style: none;    margin: 0;    padding: 0;}\n" +
223         "        ul li {    float: left;}\n" +
224         "        button{    cursor: pointer;    height: 23px;}\n" +
225         "        a:link{    text-decoration: none;}\n" +
226         "        \n" +
227         "        #div_top span,input,button,textarea{margin-left: 20px;float: left;}\n" +
228         "        .p_h1{font-size: 24px;font-weight: bolder;background-color: darkseagreen}\n" +
229         "        .p_text{font-size: 20px;font-weight: normal;text-align: left;background-color: darkseagreen}\n" +
230         "\n" +
231         "        .div_section{position:relative}\n" +
232         "        .p_a1{font-size: 20px;font-weight: normal;text-align: left;background-color: beige;margin-left: 60px;margin-right: 60px;\n" +
233         "        ;min-height: 80px;display: block;word-break: break-all;overflow-wrap: break-word;white-space: pre-wrap}\n" +
234         "        .p_a2{font-size: 20px;font-weight: normal;text-align: left;background-color: beige;left:120px}\n" +
235         "    </style>\n" +
236         "</head>";
237 </script>
238 </html>
Copy the code

View Code

This small tool has few codes and no complex functions, but I think it is unique in that it realizes the functions of “keeping”, “showing” and “modifying” information in a file like a single-celled organism. It should have certain developability, and we welcome you to open source more functions on this basis.

 

Used as an example of the article is Kant’s “critique of pure reason” (blue wu version) of the republic of China (book.sbkk8.com/waiguo/chun…).

It feels that the book has been overrated by admirers and is now more suitable for history and reference.

 

Revised on 16 February 2020:

Allows the user to add additional delimiters. The code for handling additional delimiters is as follows:

1 var str_split=document.getElementById("str_split").value; 2 if(str_split)// If there is additional split symbol 3 {4 var arr_temp=[]; 5 var arr_split=str_split.split("@"); 6 var len2=arr_split.length; 7 var str_temp="/"; 8 for(var j=0; j<len2; j++) 9 { 10 str_temp+=(arr_split[j]+(j==len2-1?" ":" | ")); 11 } 12 str_temp+="/"; 13 var var_split=eval(str_temp); 14 for(var i=0; i<len; I ++)// For each paragraph 15 {16 // 17 var section=arr_section[I]; 18 if(section.length>0) 19 { 20 arr_temp=arr_temp.concat(section.split(var_split)); 21 //arr_temp=arr_temp.splice(arr_temp.length,0,section.split(var_split)) 22 } 23 } 24 arr_section=arr_temp; 25 len=arr_section.length; 26}Copy the code

New HTML files can be in https://github.com/ljzc002/ljzc002.github.io/blob/master/%E5%93%B2%E5%AD%A6%E5%AD%A6%E4%B9%A0/Annotate4split. Download the HTML.

Revised on 26 April 2020:

Adjust page style, add text export method and style adjustment script suitable for Zhihu:

Var div_main= document.getelementById ("div_main"); 4 var arr_p=div_main.getElementsByTagName("p"); 5 var len=arr_p.length; 6 var arr_str=[]; 7 for(var i=0; i<len; i++) 8 { 9 var p=arr_p[i]; 10 if(p.className=="p_text") 11 { 12 arr_str.push(p.innerHTML); 13 } 14 else if(p.className=="p_a1") 15 { 16 arr_str.push("@"+p.innerHTML+"@"); 19 var str_res=arr_str.join("\r\n"); 20 console.log(str_res) 21 }Copy the code

Paste it into zhihu and execute it in the console of Zhihu page

1 //RichText ztext Post-RichText 2 //RichText ztext CopyrightRichText-richText 3 function addBlockQuoteZhihu(){ 4 var arr_richText=document.getElementsByClassName("RichText ztext"); 5 var len=arr_richText.length; 6 for(var i=0; i<len; i++) 7 { 8 var richText=arr_richText[i]; 9 var arr_c=richText.childNodes; 10 var len2=arr_c.length; 11 var temp_HTML=""; 12 //var temp_div=document.createElement("div"); 13 14 for(var j=0; j<len2; J++)// for each node element 15 {16 var flag=0; # 17 var node=arr_c[j]; 18 if (node. The innerHTML. Substr (0, 1) = = "@" && node. The innerHTML, substr (1, 1) = = "@") 19 {20 flag = 1; # 21 node.innerhtml = node.innerhtml. Substring (1); 22 node.innerhtml = node.innerhtml. Substring (node.innerhtml. Length -1,0); 23 temp_HTML+="<blockquote>"+node.outerHTML+"</blockquote>"; 24 //temp_div.appendChild(node.cloneNode()); //cloneNode contains only tags, no innerHTML!! 25} 26 else if(node.innerhtml. substr(0,1)=="@") 27 {28 flag=1; # 29 node.innerhtml = node.innerhtml. Substring (1); 30 temp_HTML+="<blockquote>"+node.outerHTML; 31 //temp_div.appendChild(node.cloneNode()); 33} 33 else if(node.innerhtml. substr(-1,1)=="@") 34 {35 flag=1; # 36 node.innerhtml = node.innerhtml. Substring (node.innerhtml. Length -1,0); 37 temp_HTML+=node.outerHTML+"</blockquote>"; 38 //temp_div.appendChild(node.cloneNode()); 39 } 40 if(flag==0) 41 { 42 temp_HTML+=node.outerHTML; 43 //temp_div.appendChild(node.cloneNode()); 44 } 45 } 46 richText.innerHTML=temp_HTML; 47 //richText.innerHTML=temp_div.innerHTML; 49 50 48}} / / the following compression for single script 51 / / function addBlockQuoteZhihu () {var arr_richText = document. GetElementsByClassName (RichText. ztext"); var len=arr_richText.length; for(var i=0; i<len; i++){var richText=arr_richText[i]; var arr_c=richText.childNodes; var len2=arr_c.length; var temp_HTML=""; for(var j=0; j<len2; j++){var flag=0; var node=arr_c[j]; If (node. The innerHTML. Substr (0, 1) = = "@" && node. The innerHTML, substr (1, 1) = = "@") {flag = 1; node.innerHTML=node.innerHTML.substring(1); Node. The innerHTML = node. The innerHTML. Substring (node. The innerHTML. Length 1, 0). temp_HTML+="<blockquote>"+node.outerHTML+"</blockquote>"; } else if (node. The innerHTML. Substr (0, 1) = = "@") {flag = 1; node.innerHTML=node.innerHTML.substring(1); temp_HTML+="<blockquote>"+node.outerHTML; } else if (node. The innerHTML. Substr (1, 1) = = "@") {flag = 1; Node. The innerHTML = node. The innerHTML. Substring (node. The innerHTML. Length 1, 0). temp_HTML+=node.outerHTML+"</blockquote>"; }if(flag==0){temp_HTML+=node.outerHTML; }}richText.innerHTML=temp_HTML; }}; addBlockQuoteZhihu()Copy the code

You can style the text between the @ signs separately from the body of the text so that you don’t need to style long articles.

Download: github.com/ljzc002/ljz…