
本文教你如何用html+javascript构建一个20题交互式决策问卷系统,通过dom动态渲染问题、收集用户选择,并在完成后生成可下载的个性化建议文本文件——全程无需后端,兼容所有现代浏览器。
本文教你如何用html+javascript构建一个20题交互式决策问卷系统,通过dom动态渲染问题、收集用户选择,并在完成后生成可下载的个性化建议文本文件——全程无需后端,兼容所有现代浏览器。
在浏览器环境中,JavaScript 无法直接写入本地文件系统(如 fs.writeFile),这是出于严格的安全沙箱限制;同样,HTML 本身不支持逻辑循环,所有流程控制必须由 JavaScript 在客户端完成。但好消息是:你完全可以用纯前端技术优雅地实现“20题决策问卷 + 答案汇总导出”这一目标——关键在于用 DOM 动态驱动交互流程,并利用浏览器原生的 Blob + URL.createObjectURL() 实现安全、可控的文件下载。
✅ 正确的技术路径
- HTML 结构极简化:仅保留容器和触发入口,所有问题由 js 动态插入;
- 状态驱动的问答流程:用 currentQuestionIndex 控制进度,配合数组存储 20 道结构化问题;
- 答案收集与决策树映射:为每道题设置唯一 ID 和语义化选项(如 “part-time-job”),用户选择后存入 answers = [];
- 导出为 .txt 文件:问卷结束后,将筛选出的“是”类建议拼接成文本,生成 Blob 并触发下载。
? 示例代码(完整可运行)
index.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>收入提升决策助手</title> <style> body { font-family: "Segoe UI", sans-serif; max-width: 720px; margin: 2rem auto; padding: 0 1rem; } .question { margin: 1.5rem 0; } .options button { margin-right: 0.5rem; margin-bottom: 0.5rem; padding: 0.5rem 1rem; } #result { background: #f8f9fa; padding: 1rem; border-radius: 4px; margin-top: 2rem; display: none; } </style> </head> <body> <h1>? 收入提升决策助手</h1> <div id="app"></div> <div id="result"></div> <!-- 注意:使用 defer 确保 DOM 加载完成后再执行 --> <script defer src="app.js"></script> </body> </html>
app.js
// 20 道结构化问题(可扩展) const QUESTIONS = [ { id: 'part-time-job', text: '您是否愿意接受一份兼职工作?' }, { id: 'passive-income', text: '您能否每月稳定存下一笔钱用于投资(如指数基金、债券)?' }, { id: 'yard-sale', text: '您家中是否有闲置物品可整理后举办社区跳蚤市场?' }, // ... 其余 17 题(此处省略,实际项目中补全) ]; const answers = []; // 存储用户选中的 ID(如 ['part-time-job', 'yard-sale']) let currentIndex = 0; const $app = document.getElementById('app'); const $result = document.getElementById('result'); function renderQuestion() { if (currentIndex >= QUESTIONS.Length) { showResult(); return; } const q = QUESTIONS[currentIndex]; $app.innerHTML = ` <div class="question"> <h3>第 ${currentIndex + 1} 题</h3> <p>${q.text}</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p> <div class="options"> <button onclick="selectAnswer('${q.id}', true)">✅ 是</button> <button onclick="selectAnswer('${q.id}', false)">❌ 否</button> </div> </div> `; } function selectAnswer(id, isYes) { if (isYes) answers.push(id); currentIndex++; renderQuestion(); } function showResult() { $app.innerHTML = ''; // 决策树逻辑:映射 ID → 可执行建议 const suggestions = { 'part-time-job': '✅ 申请本地咖啡馆/书店晚班,时薪约 ¥35–50,每周 12 小时可增收 ¥420+', 'passive-income': '✅ 开通证券账户定投沪深300指数基金(费率低、长期年化≈7%)', 'yard-sale': '✅ 整理旧书/玩具/小家电,在小区群发海报,单次预估收益 ¥200–800' // 实际项目中按需扩展全部 20 条 }; const selected = answers.filter(id => suggestions[id]); const content = selected.length ? selected.map(id => suggestions[id]).join('nn') : '暂未匹配到可行建议。建议重新审视资源或尝试其他方向。'; $result.innerHTML = ` <h2>? 您的个性化行动清单</h2> <pre class="brush:php;toolbar:false;" style="white-space: pre-wrap; text-align: left;">${content}
`; $result.style.display = ‘block’; } function downloadFile() { const blob = new Blob([`# 收入提升行动清单(生成于 ${new Date().toLocaleString()})nn${$result.querySelector(‘pre’).textContent}`], { type: ‘text/plain;charset=utf-8’ }); const url = URL.createObjectURL(blob); const a = document.createElement(‘a’); a.href = url; a.download = `income-action-plan-${Date.now()}.txt`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); // 释放内存 } // 启动问卷 renderQuestion();
⚠️ 关键注意事项
- 禁止使用 require(‘fs’):该模块仅 Node.js 环境可用,浏览器中会报 ReferenceError;
- 不要硬编码 20 次重复 HTML:用数组 + renderQuestion() 实现可维护性;
- 避免 while (num :直接用 currentIndex
- 下载即触发,无路径控制权:浏览器默认保存到用户“下载目录”,这是安全设计,不可绕过;
- 若需服务端持久化(如存入数据库):必须引入后端(Node.js/Python flask 等),前端仅负责提交 fetch(‘/api/save’, { method: ‘POST’, body: json.stringify(answers) })。
✅ 总结
你完全不需要切换到 Python —— HTML + JavaScript 已足够支撑此需求。核心在于:用数据驱动视图(而非模板循环)、用 Blob 替代 FS、用语义化 ID 统一管理决策逻辑。本方案零依赖、易调试、符合 Web 标准,且可无缝集成 CSS 动画、响应式布局或后续升级为 PWA。下一步建议:将 QUESTIONS 数组抽离为 JSON 文件,实现内容与逻辑分离,便于非开发者协作维护。