You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JavaScript渲染原生HTML模板:如何优雅填充模板内容?

优雅填充HTML模板的几种方案

针对你提出的模板填充需求,我分享两种实用方案,既避开逐个querySelector的繁琐,又能保证灵活性和安全性:

方案1:直接替换占位符字符串(快速适配你的双下划线模板)

如果想直接沿用你现有的双下划线占位符模板,可以通过字符串正则替换的方式快速实现,步骤如下:

  1. 获取模板内容并转为字符串
  2. 用正则匹配所有__xxx__格式的占位符,替换为对应数据
  3. 将替换后的字符串转为DOM元素

代码示例:

// 获取模板
const template = document.querySelector('template');
// 克隆模板内容(避免修改原模板)
const clone = template.content.cloneNode(true);
// 把克隆内容转为字符串
let templateHtml = clone.innerHTML;

// 待填充数据(保留你原有的双下划线格式)
const data = {
  __heading__: 'Lots of things',
  __label1__: 'label 1',
  __value1__: 'value 1',
  __label2__: 'label 2',
  __value2__: 'value 2',
  __instruction__: 'Do the thing',
  __label3__: 'label 3',
  __value3__: 'value 3',
};

// 正则替换所有占位符,没有对应数据则保留原占位符
templateHtml = templateHtml.replace(/__(\w+)__/g, (match, key) => {
  return data[`__${key}__`] || match;
});

// 将替换后的HTML转回DOM元素
const parser = new DOMParser();
const renderedElement = parser.parseFromString(templateHtml, 'text/html').body.firstChild;

// 把渲染好的元素添加到页面
document.body.appendChild(renderedElement);

⚠️ 注意:这种方法如果数据包含未过滤的HTML内容,会有XSS风险,只适合可信数据源的场景。


方案2:自定义属性标记(更安全、可维护的优雅方案)

如果你愿意调整模板格式,推荐用自定义属性标记需要填充的元素和属性,这种方式更灵活,也能避免XSS问题,容错性更高:

修改后的模板:

<template id="my-template">
  <div>
    <h2 data-template-key="heading"></h2>
    <label data-template-key="label1"></label>
    <input type="text" data-template-key="value1" data-template-attr="value">
    <label data-template-key="label2"></label>
    <input type="text" data-template-key="value2" data-template-attr="value">
    <div data-template-key="instruction"></div>
    <label data-template-key="label3"></label>
    <input type="text" data-template-key="value3" data-template-attr="value">
  </div>
</template>
  • data-template-key:标记该元素对应的数据键名
  • data-template-attr:可选,标记要填充的是元素的属性(比如input的value),默认填充textContent

对应的简化数据:

const data = {
  heading: 'Lots of things',
  label1: 'label 1',
  value1: 'value 1',
  label2: 'label 2',
  value2: 'value 2',
  instruction: 'Do the thing',
  label3: 'label 3',
  value3: 'value 3',
};

通用渲染函数:

function renderTemplate(templateId, data) {
  const template = document.getElementById(templateId);
  const clone = template.content.cloneNode(true);
  
  // 遍历所有带标记的元素
  clone.querySelectorAll('[data-template-key]').forEach(element => {
    const key = element.dataset.templateKey;
    const value = data[key];
    
    if (!value) return; // 没有对应数据则跳过
    
    // 判断是填充文本内容还是属性
    const attr = element.dataset.templateAttr;
    if (attr) {
      element.setAttribute(attr, value);
    } else {
      element.textContent = value;
    }
  });
  
  return clone.firstElementChild;
}

// 调用渲染并添加到页面
const rendered = renderTemplate('my-template', data);
document.body.appendChild(rendered);

这种方案的优势:

  • 无需依赖固定的元素顺序或标签类型,结构变动也不影响渲染
  • 用textContent和setAttribute避免XSS注入,安全性更高
  • 代码可复用,后续新增模板或数据字段只需对应添加标记即可

内容的提问来源于stack exchange,提问作者run_the_race

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:47:35