在做项目中遇到一个很棘手的问题。无奈解决思路有了,学艺不精,正则表达式不会写了,悲催之际!
需求:使用JavaScript来动态管理文章目录结构
在我们编辑文章目录的时候,通常都是用文本编辑器工具中的 "有序列表" / "无序列表" 进行生成结构
然后查看源代码方式,将标签内容粘贴在自己的html网页中。
通常这种方法是非常简单而又有效的。
但是,如果需要编辑的量,如果较多的话(具体不讨论具体量数),那么这么手工的人脑排版就会显得非常的耗时费脑。
所以,我在想有没有更好的方法应对庞大的编辑量呢?
于是,想到了之前编辑的一篇文章:https://www.youcl.com/info/2937 使用JS正则表达式来动态改变文本内容
我的思路是这样的:
第一步:将目录内容统统使用<p>标签
第二步:仿照根据 JavaScript正则表达式简单应用 这篇文章,使用正则表达式进行排版
期待完成的目标
将每一个匹配的<p>标签最后的数字,替换改变增加左边距10个像素、加粗显示
将“第1章”、“第2章”、“第3章”... 这种规则的<p>标签修改为<h4>标签;
将“1.1”、“1.2”、“1.3”... 这种规则的<p>标签加上css样式“text-indent:1em”并将该规则的序号文字改变为红色;
将“1.1.1”、“1.1.2”、“1.2.1”、“1.3.1”... 这种规则的<p>标签加上css样式“text-indent:2em”;
理想状态下的类似格式如下图
测试代码如下:
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> html{font-size: 13px;} #mulu{ padding: 20px; font-family: "微软雅黑"; background: #dcf3dc; margin-left: 30px; } </style> </head> <body> <div id="mulu"> <p>第1章 第三方JavaScript介绍 1</p> <p>1.1 第三方JavaScript的定义 2</p> <p>1.2 第三方JavaScript的用法 4</p> <p>1.2.1 嵌入式微件 6</p> <p>1.2.2 分析和统计 8</p> <p>1.2.3 Web服务API封装 9</p> <p>1.3 开发一个简单的微件 13</p> <p>1.3.1 服务端生成脚本 14</p> <p>1.3.2 通过iframes分发微件 16</p> <p>1.4 第三方开发的挑战 17</p> <p>1.4.1 未知的上下文 17</p> <p>1.4.2 共享环境 18</p> <p>1.4.3 浏览器限制 19</p> <p>1.5 总结 19</p> <p>第2章 应用的分发和加载 20</p> <p>2.1 配置第三方开发环境 21</p> <p>2.1.1 发布者的测试页面 21</p> <p>2.1.2 Web服务器 22</p> <p>2.1.3 模拟多个域 23</p> <p>2.2 加载初始的脚本 24</p> <p>2.2.1 阻塞式脚本引入 25</p> <p>2.2.2 使用async和defer无阻塞加载脚本 26</p> <p>2.2.3 动态脚本插入 28</p> <p>2.3 初始脚本文件 29</p> <p>2.3.1 window和undefined混淆 30</p> <p>2.3.2 基本应用程序流程 31</p> <p>2.4 加载额外的文件 32</p> <p>2.4.1 JavaScript文件 33</p> <p>2.4.2 库 35</p> <p>2.5 脚本参数传递 37</p> <p>2.5.1 使用查询字符串 37</p> <p>2.5.2 使用片段标识符 40</p> <p>2.5.3 使用自定义数据属性 40</p> <p>2.5.4 使用全局变量 42</p> <p>2.6 获取应用数据 44</p> <p>2.7 总结 45</p> <p>第3章 HTML和CSS的渲染 46</p> <p>3.1 输出HTML 47</p> <p>3.1.1 使用document.write 47</p> <p>3.1.2 追加到已知位置 48</p> <p>3.1.3 追加多个微件 50</p> <p>3.1.4 解耦渲染对象 52</p> <p>3.2 为你的HTML添加样式 53</p> <p>3.2.1 使用内联样式 53</p> <p>3.2.2 加载CSS文件 54</p> <p>3.2.3 嵌入CSS到 JavaScript中 56</p> <p>3.3 防御性的HTML和CSS 59</p> <p>3.3.1 命名空间59</p> <p>3.3.2 CSS的特殊性 60</p> <p>3.3.3 过度设置CSS的特殊性 62</p> <p>3.4 将内容嵌入到iframe中 65</p> <p>3.4.1 没有设置src的iframe 66</p> <p>3.4.2 外部iframe 68</p> <p>3.4.3 样式继承 69</p> <p>3.4.4 何时避免使用iframe 73</p> <p>3.5 小结 74</p> <p>第4章 与服务器通信 75</p> <p>4.1 AJAX和浏览器的同源策略 76</p> <p>4.1.1 判定同源的规则 77</p> <p>4.1.2 同源策略和脚本加载 78</p> <p>4.2 带填充的JSON(JSONP) 80</p> <p>4.2.1 通过脚本元素加载JSON 80</p> <p>4.2.2 动态的回调函数 81</p> <p>4.2.3 局限性和安全问题 84</p> <p>4.3 子域名代理 85</p> <p>4.3.1 使用document.domain更改文档的源 87</p> <p>4.3.2 使用子域代理实现跨域通信 88</p> <p>4.3.3 子域名代理与JSONP相结合 91</p> <p>4.3.4 Internet Explorer和子域代理 94</p> <p>4.3.5 安全隐患 95</p> <p>4.4 跨源资源共享 95</p> <p>4.4.1 发送简单的HTTP请求 96</p> <p>4.4.2 使用CORS传输</p> <p>Cookie 98</p> <p>4.4.3 发送预检请求 99</p> <p>4.4.4 浏览器支持 99</p> <p>4.5 总结 100</p> <p>第5章 跨域iframe通信 101</p> <p>5.1 HTML5 window.postMessage API 102</p> <p>5.1.1 使用window.postMessage发送信息 103</p> <p>5.1.2 接收发送给窗口的消息 104</p> <p>5.1.3 浏览器的支持 106</p> <p>5.2 降级技术 107</p> <p>5.2.1 使用window.name发送消息 108</p> <p>5.2.2 使用URL片段标识符发送消息 111</p> <p>5.2.3 使用Flash发送消息 113</p> <p>5.3 使用easyXDM简化跨域消息通信 116</p> <p>5.3.1 加载并初始化easyXDM 116</p> <p>5.3.2 使用easyXDM.Socket发送简单信息 118</p> <p>5.3.3 使用easyXDM.Rpc定义JSON-RPC接口 119</p> <p>5.4 总结 124</p> <p>第6章 验证和会话 125</p> <p>6.1 第三方Cookie 126</p> <p>6.1.1 Sessions的设置和读取 127</p> <p>6.1.2 禁用第三方Cookie 128</p> <p>6.1.3 Internet Explorer和P3P头 129</p> <p>6.1.4 检测cookies是否可用 131</p> <p>6.2 设置第三方cookie 134</p> <p>6.2.1 使用独立窗口 134</p> <p>6.2.2 iframe的解决方案(只针对Safari) 137</p> <p>6.2.3 Chrome和Firefox中的单页面会话 140</p> <p>6.3 会话安全 140</p> <p>6.3.1 HTTPS和更安全的cookie 141</p> <p>6.3.2 多级身份认证 142</p> <p>6.4 总结 144</p> <p>第7章 安全性 145</p> <p>7.1 Cookies,会话,和会话窃取 146</p> <p>7.2 跨站脚本 147</p> <p>7.2.1 XSS攻击 148</p> <p>7.2.2 CSS中的XSS漏洞 149</p> <p>7.2.3 防止XSS对应用的攻击 151</p> <p>7.3 跨站请求伪造 153</p> <p>7.3.1 XSRF攻击 154</p> <p>7.3.2 JSON劫持 155</p> <p>7.3.3 保护应用免受XSRF攻击 156</p> <p>7.4 发布者漏洞 158</p> <p>7.4.1 发布者模拟 158</p> <p>7.4.2 点击劫持 160</p> <p>7.4.3 拒绝服务 162</p> <p>7.5 总结 162</p> <p>第8章 独特的框架 163</p> <p>8.1 实现一个最基本的SDK 165</p> <p>8.1.1 初始化 166</p> <p>8.1.2 异步加载 167</p> <p>8.1.3 暴露公共方法 170</p> <p>8.1.4 事件监听器 170</p> <p>8.2 版本管理 173</p> <p>8.2.1 URL版本管理 174</p> <p>8.2.2 通过初始化进行版本控制 176</p> <p>8.3 封装Web服务的APIs 178</p> <p>8.3.1 在客户端访问Web服务APIs 179</p> <p>8.3.2 封装Camera Stork API 182</p> <p>8.3.3 识别发布者 186</p> <p>8.3.4 用户授权和OAuth 190</p> <p>8.4 总结 191</p> <p>第9章 性能 193</p> <p>9.1 优化负荷 194</p> <p>9.1.1 合并和压缩源代码 195</p> <p>9.1.2 减少图像请求 196</p> <p>9.1.3 缓存文件 198</p> <p>9.1.4 推迟HTTP请求 199</p> <p>9.2 JavaScript优化 204</p> <p>9.2.1 浏览器内部:UI线程,重绘和回流 205</p> <p>9.2.2 控制耗性能的调用:throttle和debounce函数 206</p> <p>9.2.3 使用setTimeout延迟计算 208</p> <p>9.3 被感知的性能 210</p> <p>9.3.1 对用户的操作保持乐观 211</p> <p>9.3.2 在文档就绪之前渲染 212</p> <p>9.4 总结 213</p> <p>第10章 调试和测试 215</p> <p>10.1 调试 216</p> <p>10.1.1 在生产环境中使用开发环境的代码 218</p> <p>10.1.2 单步执行代码 223</p> <p>10.2 测试 227</p> <p>10.2.1 单元测试、集成测试和回归测试 228</p> <p>10.2.2 使用QUnit编写回归测试 230</p> <p>10.2.3 使用Hiro写回归测试 233</p> <p>10.3 总结 236</p> <p> <br/> </p> </div> </body> <script type="text/javascript"> // 简单实例 var wrapDom = document.getElementById('mulu'); var text = wrapDom.innerHTML; text = text.replace('第1章','<span style=\'font-size: larger;color: deeppink;font-weight: 600;\'>第1章</span>'); wrapDom.innerHTML = text; </script> </html>
最后的解决方案
在技术交流群中,遇到一位大神,最终的解决方案如下,非常非常非常感谢他的解答
$("#mulu p").each(function(){ var e =$(this); var f=e.html(); if (f.match(/(第[0-9]+章)/)) { e.html(('<h4>'+f+'</h4>').replace(/(第[0-9]+章)/,"<span style=\'font-size: larger;color: deeppink;font-weight: 600;\'>$1</span>")); }else if(f.match(/\d\.\d\.\d/)){ e.css("text-indent","4em"); }else if (f.match(/\d\.\d/)) { e.css("text-indent","2em"); } }); // 上述代码优化之后 $("#mulu p").each(function(){ var e =$(this); var f=e.html(); var l=(f.match(/\d\.\d\.\d/))?4:(f.match(/\d\.\d/))?2:0; if (f.match(/(第[0-9]+章)/)) { e.html(('<h4>'+f+'</h4>')); }else if(!!l){ e.css("text-indent",l+"em"); } });
实战运用示例图
总结
最终看到解决代码的那一刻是不是一下子释然了,比预期的要简单,比预想的要方便。 看来在提升自身技能的同时,还需要灵活变通才最重要。