jQuery如何使用contains选择器选取最近元素并替换模板占位符
问题根因
你的代码无法正常运行主要有三个核心原因:
- 选择器
$(".notes *:contains('{{')")会命中所有包含{{字符的元素,包括嵌套的父级元素(比如示例里的table、tr、td都会被选中),会导致内容被重复处理。 - 正则默认只匹配第一个符合规则的变量,当同一个元素内存在多个
{{变量}}时(比如示例中的p标签同时包含{{my_name}}和{{my_email}}),第二个变量会被漏掉无法替换。 - 直接取match结果的索引值,如果处理过程中元素内已经没有
{{变量}},会直接抛出索引异常导致代码中断。
修复方案
你可以用文本节点遍历+全局正则替换的方案,既能保留原有DOM结构和元素上绑定的事件,又能一次性处理所有变量,后续新增变量只需修改映射表即可:
// 变量映射表,新增变量直接在这里加键值对即可 const varMap = { my_name: "Tony", my_email: "tonyhawk@gmail.com" }; $(".notes *").contents().each(function() { // 只处理文本节点,不会修改元素属性和结构 if (this.nodeType === 3) { // 全局匹配所有{{xxx}}格式的变量,用回调对应替换 this.textContent = this.textContent.replace(/{{(.*?)}}/g, (match, key) => { return varMap[key] ?? match; }) } })
完整可运行代码如下:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> const varMap = { my_name: "Tony", my_email: "tonyhawk@gmail.com" }; $(".notes *").contents().each(function() { if (this.nodeType === 3) { this.textContent = this.textContent.replace(/{{(.*?)}}/g, (match, key) => { return varMap[key] ?? match; }) } }) </script> <div class="notes"> <h4>{{my_name}}</h4> <table> <tr> <td> <p>{{my_name}}, {{my_email}}</p> </td> </tr> </table> </div>
内容的提问来源于stack exchange,提问作者nayakaraga
相关产品推荐
相关产品推荐

