H5--预定义字符&实体字符

本文深入讲解HTML中的预定义字符和实体字符,包括它们的使用场景、编码格式及在HTML、CSS、JavaScript中的应用规范,帮助读者理解如何在网页中正确显示特殊符号。

预定义字符&实体字符

预定义字符简介:

HTML中预定义字符是指:<,>,&等有特殊含义(<,>,用于链接签,&用于转义),不能直接使用。

转义字符串/实体字符/字符实体:

上述的预定义符号是不显示在我们最终看到的网页里的,那如果希望在网页中显示这些符号,该怎么办呢?
这里就涉及到HTML转义字符串(Escape Sequence)也称字符实体(Character Entity)。

转义字符串/实体字符/字符实体缘由:

像“<”和“>”这类符号已经用来表示HTML标签,因此就不能直接当作文本中的符号来使用。
为了在HTML文档中使用这些符号,就需要定义它的转义字符串。当解释程序遇到这类字符串时就把它解释为真实的字符。在输入转义字符串时,要严格遵守字母大小写的规则

实体字符使用方法

编码格式

实体字符属于unicode字符集,所以文档需要声明编码格式为UTF-8

<meta charset="utf-8">
实体字符目录查阅使用教程

①HTML文档中,需要在编号前面加上“&#”符号
②CSS文档中,需要在编号前面加上反斜杠“\”进行转义
③JS文档中,需要在编号前面加上“\u”来进行转义

HTML使用规范

第一列编号用于HTML文档中,使用时需要在编号前面加上“&#”符号,以;结尾。
比如“向左箭头”符号对应的HTML编号是:“8592”,那么在文档中需要写成“&#8592”;即 向左箭头为&#8592,最终展示结果为:向左箭头为←

CSS使用规范

第三列编号用于CSS文档中,需要在编号前面加上反斜杠“\”进行转义
比如说“√”符号对应的CSS编号是:“2714”,那么在文档中需要写成“\2714”;

JS使用规范

第二列编号用于JavaScript文档中,需要在编号前面加上“u”来进行转义,比如说“√”符号,在JavaScript文档中就要写成“\u2714”

兼容

在这里插入图片描述
PS:基于上面几个不足之处,在使用过程需要考虑兼容,不要滥用

你遇到的问题是:**关键词没有高亮显示**,尽管代码中使用了正则替换并生成了带有 `&lt;span class=&quot;highlight&quot;&gt;` 的 HTML 字符串,但 `rich-text` 并未正确渲染样式。 这个问题在 **微信小程序、UniApp、Taro 等基于 `rich-text` 组件的框架中非常常见**。下面我们来 **详细分析原因并提供完整解决方案**。 --- ## ✅ 问题原因分析 ### 1. `rich-text` 不支持外部 CSS 类名(`.highlight`) - 在微信小程序或 UniApp 中,`&lt;rich-text :nodes=&quot;...&quot;&gt;` 虽然可以渲染 HTML 标签,但: - **它不会应用你在 `.vue` 文件中写的 CSS 类(如 `.highlight`)** - 即使你在 `style` 中写了 `.highlight { color: red; }`,也不会生效! &gt; 📌 原因:`rich-text` 渲染的内容是在一个隔离环境中的,无法继承组件样式作用域。 --- ### 2. 正确做法:使用内联样式(inline style) 你应该把样式直接写进 HTML 标签里: ```html &lt;span style=&quot;color: #007AFF; font-weight: bold;&quot;&gt;匹配的词&lt;/span&gt; ``` 而不是依赖类名 `.highlight`。 --- ### 3. `escapeHTML` 可能影响正则匹配(可选优化) 如果你对 `query` 和 `text` 都做了 HTML 转义(比如将 `&lt;` &rarr; `&lt;`),那么你在用正则匹配原始关键词时可能会失败,因为文本已经被转义。 例如: - 用户输入 `&quot;a&quot;`,实际要匹配的是 `&quot;a&quot;`,但如果 `escapedText` 是 `&quot;co&amp;lt;&quot;`,那 `a` 就找不到。 所以建议:**先做高亮替换,再整体转义;或者只对非标签部分进行安全处理** --- ## ✅ 正确修复方案 ### ✅ 修改 `renderItemText` 方法(关键修改点) ```js renderItemText(item) { const text = item[this.showField] || &#39;&#39; const query = this.inputValue.trim() if (!query || !text) { return this.escapeHTML(text) } // 先对原始文本和查询词做 HTML 转义 const escapedText = this.escapeHTML(text) const escapedQuery = this.escapeHTML(query) // 构造不区分大小写的全局匹配正则(注意:必须确保 query 已转义) const regex = new RegExp(`(${escapedQuery})`, &#39;gi&#39;) // 替换所有匹配项为带样式的 span(使用 inline style) const highlighted = escapedText.replace( regex, &#39;&lt;span style=&quot;color: #007AFF; font-weight: bold;&quot;&gt;$1&lt;/span&gt;&#39; ) return `&lt;div&gt;${highlighted}&lt;/div&gt;` }, ``` --- ### ✅ 添加 `escapeHTML` 工具函数(防止 XSS) ```js methods: { escapeHTML(str) { if (typeof str !== &#39;string&#39;) return &#39;&#39; const div = document.createElement(&#39;div&#39;) div.textContent = str return div.innerHTML // 转成 HTML 实体 }, // ...其他方法 } ``` &gt; ⚠️ 注意:H5 环境可用 `document`,但在小程序中不能运行 DOM 操作。 &gt; 所以如果你需要兼容小程序,请改用字符串替换方式: ```js escapeHTML(str) { if (typeof str !== &#39;string&#39;) return &#39;&#39; return str .replace(/&amp;/g, &#39;&amp;&#39;) .replace(/&lt;/g, &#39;&lt;&#39;) .replace(/&gt;/g, &#39;&gt;&#39;) .replace(/&quot;/g, &#39;&quot;&#39;) .replace(/&#39;/g, &#39;&#39;&#39;) } ``` --- ### ✅ 确保 `rich-text` 支持 HTML 渲染 确认你的平台支持 `nodes` 接收 HTML 字符串。例如在 UniApp 中没问题,在 Taro 微信小程序也支持。 --- ### ✅ (可选)测试输出调试 你可以临时加个 `console.log(renderItemText(...))` 查看返回的 HTML 是否包含 `&lt;span style=&quot;...&quot;&gt;`,例如: ```js console.log(this.renderItemText({ name: &#39;北京大厦&#39; })) // 输出:&lt;div&gt;北&lt;span style=&quot;color: #007AFF&quot;&gt;京&lt;/span&gt;大厦&lt;/div&gt; ``` 如果看不到 `style`,说明上面逻辑有问题。 --- ## ✅ 最终有效示例代码片段 ```js renderItemText(item) { const text = item[this.showField] || &#39;&#39; const query = this.inputValue.trim() if (!query || !text) return this.escapeHTML(text) const escapedText = this.escapeHTML(text) const escapedQuery = this.escapeHTML(query) const regex = new RegExp(`(${escapedQuery})`, &#39;gi&#39;) const highlighted = escapedText.replace( regex, &#39;&lt;span style=&quot;color: #007AFF; font-weight: bold;&quot;&gt;$1&lt;/span&gt;&#39; ) return `&lt;div&gt;${highlighted}&lt;/div&gt;` }, escapeHTML(str) { if (typeof str !== &#39;string&#39;) return &#39;&#39; return str .replace(/&amp;/g, &#39;&amp;&#39;) .replace(/&lt;/g, &#39;&lt;&#39;) .replace(/&gt;/g, &#39;&gt;&#39;) .replace(/&quot;/g, &#39;&quot;&#39;) .replace(/&#39;/g, &#39;&#39;&#39;) } ``` --- ## ✅ 补充建议:避免 key 直接用 index ```vue &lt;!-- ❌ 不推荐 --&gt; &lt;v-for=&quot;(item, index) in list&quot; :key=&quot;index&quot;&gt; &lt;!-- ✅ 推荐 --&gt; :v-for=&quot;(item, index) in list&quot; :key=&quot;index + item[showField]&quot; ``` 防止列表变化导致虚拟 DOM 错误复用。 --- ## ✅ 总结 | 问题 | 解决方案 | |------|----------| | 没有高亮 | 使用 `style=&quot;...&quot;` 内联样式,不要用 `.highlight` 类 | | 样式不生效 | `rich-text` 不读取组件 CSS,只能靠内联样式 | | 匹配失败 | 查询词和文本都需同步转义后再匹配 | | 安全性 | 手动实现 `escapeHTML` 防止 XSS | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值