JS 正则表达式动态改变HTML文章目录结构

在做项目中遇到一个很棘手的问题。无奈解决思路有了,学艺不精,正则表达式不会写了,悲催之际!

需求:使用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");
	}
});

实战运用示例图


总结

最终看到解决代码的那一刻是不是一下子释然了,比预期的要简单,比预想的要方便。 看来在提升自身技能的同时,还需要灵活变通才最重要。



赞(52) 打赏
未经允许不得转载:优客志 » 前端设计
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏