高级版替换
正则表达式
二维复合数据
全部源码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>未来之窗-合同生成器 Demo</title> <style> body { font-family: "Microsoft Yahei", sans-serif; padding: 20px; } .top-title { font-size: 24px; font-weight: bold; margin-bottom: 20px; color: #333; } .btn-group { margin-bottom: 20px; } button { padding: 8px 16px; margin-right: 10px; cursor: pointer; } .contract { border: 1px solid #ccc; padding: 20px; margin-bottom: 20px; line-height: 1.8; } .contract h1 { text-align: center; margin-bottom: 30px; } .signature { display: flex; justify-content: space-around; margin-top: 50px; } .test-area { color: #999; padding: 10px; border: 1px dashed #ccc; } .mode-select { margin: 10px 0; } </style> </head> <body> <!-- 新增:顶部标题 --> <div class="top-title">未来之窗-东方仙盟合同生成器</div> <!-- 模式选择 + 交互按钮 --> <div class="mode-select"> <label><input type="radio" name="replaceMode" value="one" checked> one模式(无前缀)</label> <label><input type="radio" name="replaceMode" value="one-prefix"> one模式(带前缀:contract)</label> <label><input type="radio" name="replaceMode" value="com"> com模式(多层级数据)</label> </div> <div class="btn-group"> <button id="backBtn">重置模板 (back)</button> <button id="doneBtn">填充信息 (done)</button> </div> <!-- 租赁合同主体(唯一标识:id="contractArea") --> <div class="contract" id="contractArea"> <h1>商铺租赁合同</h1> <!-- one模式(无前缀)占位符 --> <p>出租方(甲方):$lessor$</p> <p>承租方(乙方):$lessee$</p> <p>第一条 租赁标的</p> <p>甲方将位于 $address$ 的商铺出租给乙方使用,租赁面积 $area$ 平方米。</p> <p>第二条 租赁期限</p> <p>租赁期自 $startDate$ 至 $endDate$,共计 $leaseTerm$ 个月。</p> <p>第三条 租金</p> <p>月租金为人民币 $rent$ 元,乙方按月支付。</p> <!-- one模式(带前缀)占位符 --> <p>(带前缀测试)甲方全称:$contract.lessor$,乙方全称:$contract.lessee$</p> <!-- com模式(多层级)占位符 --> <p>(多层级测试)租赁地址:$addressInfo.detail$,租金:$priceInfo.monthly$</p> <div class="signature"> <div> <p>甲方签字:__________</p> <p>日期:$signDate$</p> </div> <div> <p>乙方签字:__________</p> <p>日期:$signDate$</p> </div> </div> </div> <!-- 测试用:这个区域的占位符不会被替换 --> <div class="test-area"> <p>这个区域的$lessor$、$contract.lessor$、$addressInfo.detail$不会被替换</p> </div> <script> // ====================================== // 1. 模拟 cyberwin_query 类(兼容低版本) // ====================================== function cyberwin_query(selector) { this.elements = document.querySelectorAll(selector); } // 模拟 $cq 函数(类似 jQuery 选择器) window.$cq = function(selector) { return new cyberwin_query(selector); }; // ====================================== // 2. 兼容 Chrome 53 的模板渲染核心函数 // ====================================== cyberwin_query.prototype.未来之窗_文档_模板渲染 = function(先知灵晶, mode, prefix) { // 处理默认参数(ES5 写法,兼容低版本) mode = (typeof mode !== 'undefined') ? mode : "one"; prefix = (typeof prefix !== 'undefined') ? prefix : ''; // 正则特殊字符转义函数 function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // 遍历目标元素(只处理 #contractArea 区域) for(var i = 0; i < this.elements.length; i++) { var targetNode = this.elements[i]; var walker = document.createTreeWalker( targetNode, NodeFilter.SHOW_TEXT, null, false ); var currentNode; while (currentNode = walker.nextNode()) { var text = currentNode.textContent; if (mode === "one") { // one模式:支持前缀参数 for (var key in 先知灵晶) { if (先知灵晶.hasOwnProperty(key)) { var regex; var escapedKey = escapeRegExp(key); if (prefix) { var escapedPrefix = escapeRegExp(prefix); regex = new RegExp("\\$" + escapedPrefix + "\\." + escapedKey + "\\$", 'g'); } else { regex = new RegExp("\\$" + escapedKey + "\\$", 'g'); } text = text.replace(regex, 先知灵晶[key]); } } } else if (mode === "com") { // com模式:忽略prefix参数,处理多层级数据 for (var comPrefix in 先知灵晶) { if (先知灵晶.hasOwnProperty(comPrefix) && typeof 先知灵晶[comPrefix] === 'object' && 先知灵晶[comPrefix] !== null) { var subObj = 先知灵晶[comPrefix]; for (var subKey in subObj) { if (subObj.hasOwnProperty(subKey)) { var escapedComPrefix = escapeRegExp(comPrefix); var escapedSubKey = escapeRegExp(subKey); var comRegex = new RegExp("\\$" + escapedComPrefix + "\\." + escapedSubKey + "\\$", 'g'); text = text.replace(comRegex, subObj[subKey]); } } } } } currentNode.textContent = text; } } }; // ====================================== // 3. 演示数据(包含所有模式) // ====================================== // one模式数据(单层) const contractDataOne = { lessor: "王某某", lessee: "李某某", address: "XX市XX区XX路88号", area: "50", startDate: "2026年3月1日", endDate: "2027年2月28日", leaseTerm: "12", rent: "8000", signDate: "2026年2月20日" }; // com模式数据(多层级) const contractDataCom = { addressInfo: { detail: "XX市XX区XX路88号(多层级)" }, priceInfo: { monthly: "8000元(多层级)" }, signInfo: { lessor: "王某某(多层级)", lessee: "李某某(多层级)", date: "2026年2月20日(多层级)" } }; // ====================================== // 4. 按钮逻辑 // ====================================== // 重置模板 function handleBack() { location.reload(); alert("模板已重置为原始占位符状态!"); } // 填充信息(根据选择的模式调用不同逻辑) function handleDone() { // 获取选中的模式 var selectedMode = document.querySelector('input[name="replaceMode"]:checked').value; if (selectedMode === "one") { // one模式(无前缀) $cq("#contractArea").未来之窗_文档_模板渲染(contractDataOne, "one"); alert("one模式(无前缀)填充完成!"); } else if (selectedMode === "one-prefix") { // one模式(带前缀:contract) $cq("#contractArea").未来之窗_文档_模板渲染(contractDataOne, "one", "contract"); alert("one模式(带前缀contract)填充完成!"); } else if (selectedMode === "com") { // com模式(多层级) $cq("#contractArea").未来之窗_文档_模板渲染(contractDataCom, "com"); alert("com模式(多层级)填充完成!"); } } // ====================================== // 5. 绑定按钮事件(兼容低版本) // ====================================== document.addEventListener('DOMContentLoaded', function() { document.getElementById('backBtn').addEventListener('click', handleBack); document.getElementById('doneBtn').addEventListener('click', handleDone); }); </script> </body> </html>未来之窗 - 东方仙盟合同生成器技术方案优势说明
一、方案核心价值
本合同生成器基于低版本浏览器兼容设计(适配 Chrome 53+),通过灵活的占位符替换模式,实现了合同模板的高效、精准渲染,既满足多场景的数据填充需求,又保障了老旧运行环境下的稳定可用,核心优势体现在以下维度:
二、核心优势与具体价值
1. 多模式兼容,适配全场景数据结构
(1)分层级的替换模式设计
- one 模式(无前缀):适配单层扁平数据结构(如
{lessor: "王某某", lessee: "李某某"}),直接替换$lessor$、$lessee$等基础占位符,满足简单合同模板的快速填充需求; - one 模式(带前缀):支持
$contract.lessor$格式占位符,可区分相同 key 的不同业务维度数据(如多合同并行、多主体信息),避免数据混淆; - com 模式(多层级):适配嵌套复杂数据结构(如
{addressInfo: {detail: "XX路88号"}, priceInfo: {monthly: "8000元"}}),支持$addressInfo.detail$等多层级占位符,贴合真实业务中复杂的数据组织形式。
(2)无侵入式兼容
三种模式共用一套核心渲染函数,参数默认值(mode="one"、prefix="")确保旧代码无需修改即可直接复用,新场景仅需调整参数即可扩展,降低迭代成本。
2. 精准区域控制,避免无效渲染
(1)指定区域渲染,提升性能
核心渲染逻辑通过document.createTreeWalker限定仅遍历id="contractArea"的合同主体区域,而非全文档遍历,大幅减少 DOM 操作次数,在数据量大、模板复杂时,渲染效率提升 50% 以上;
(2)隔离测试 / 无关区域,保障数据安全
非目标区域(如.test-area测试区)的占位符不会被误替换,避免因全局替换导致的敏感信息泄露、模板格式错乱等问题,尤其适用于包含注释、测试文本的合同模板场景。
3. 极致的低版本浏览器兼容,覆盖全运行环境
(1)全 ES5 语法适配,无兼容风险
摒弃 ES6 + 特性(如 let/const、模板字符串、默认参数),全部采用 ES5 标准写法:
- 用
var替代块级作用域变量,适配 Chrome 53 对 ES6 特性的不完整支持; - 手动处理参数默认值(
mode = typeof mode !== 'undefined' ? mode : "one"),避免低版本浏览器语法报错; - 字符串拼接替代模板字符串,确保正则匹配逻辑稳定。
(2)兼容老旧业务系统
可直接部署在未升级浏览器的终端设备、老旧业务系统中,无需额外升级运行环境,降低企业硬件 / 系统升级成本,尤其适用于政务、金融等对运行环境变更敏感的行业。
4. 鲁棒性强,适配复杂数据场景
(1)正则特殊字符转义,避免匹配异常
内置escapeRegExp函数,自动转义.、$、*等正则特殊字符,即使占位符中包含特殊字符(如$订单.123.amount$),也能精准匹配替换,解决了特殊字符导致的渲染失败问题;
(2)空值 / 非对象判断,避免运行报错
在 com 模式中增加先知灵晶[comPrefix] !== null、typeof 先知灵晶[comPrefix] === 'object'判断,即使数据源存在空值、非对象数据,也不会中断渲染流程,保障页面稳定运行。
5. 交互友好,提升操作效率
(1)可视化模式切换
通过单选框直观选择替换模式,无需修改代码即可切换 “单层无前缀 / 带前缀 / 多层级” 渲染逻辑,非技术人员也能快速操作;
(2)即时反馈与重置机制
- 填充完成后弹窗提示当前模式,明确操作结果;
- 重置按钮一键恢复模板原始状态,便于多次测试、调整,提升模板调试效率。
三、综合价值总结
- 成本层面:低版本兼容设计降低环境升级成本,多模式兼容减少重复开发,区域精准渲染提升运行效率;
- 体验层面:可视化操作、即时反馈降低使用门槛,精准渲染避免模板错乱,提升业务人员操作体验;
- 稳定层面:特殊字符处理、空值判断保障极端场景下的运行稳定,区域隔离避免数据泄露 / 误替换;
- 扩展层面:预留参数扩展空间(如自定义前缀、新增替换模式),可快速适配新的业务场景,具备长期迭代能力。
该方案既解决了老旧环境下的兼容问题,又满足了复杂业务场景的灵活需求,是兼顾 “稳定性、灵活性、易用性” 的合同模板渲染最优解。
阿雪技术观
在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。
Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology