JavaScript实现点击按钮动态添加可编辑问卷选项与问题
可编辑模拟调查问卷动态功能实现
核心解决两类动态DOM操作需求:给指定问题新增选项、新增完整的可编辑问题块,具体实现如下:
核心逻辑
- 把重复结构(单条选项、单个问题块)抽成统一的生成函数,保证初始加载内容和后续动态新增内容的功能、样式完全一致
- 点击「Add Option」时,先定位按钮所属的问题容器,仅在当前容器内插入新选项,不会干扰其他问题
- 新增全局「Add Question」按钮,点击时生成带初始选项、独立Add Option按钮的完整问题块,插入到表单末尾
完整可运行代码
HTML 部分
调整原有硬编码结构,新增问题容器和全局新增问题按钮,初始问题通过JS动态生成:
<html> <head> <title>Your Survey Form</title> <link rel="stylesheet" href="DemoSurveyStyle.css"> </head> <body> <form> <h1 id="myText" contenteditable="true">Survey Name</h1> <!-- 所有问题块统一存放在这个容器中 --> <div id="questionContainer"></div> <!-- 全局新增问题按钮 --> <button type="button" id="addQuestionBtn" style="margin-top:20px;">Add Question</button> </form> <script src="DemoCode.js"></script> </body> </html>
CSS 部分
微调原有样式,修复选项固定左外边距导致的布局错位问题:
body { background-color: #00ffaa; font-family: Verdana; text-align: center; } .questionName { margin-top: 25px; font-size: 20px; } .optionName { margin-top: 8px; font-size: 15px; font-style: italic; text-align: left; } .box { margin-top: 12px; margin-left: 10px; } .option { display: flex; align-items: center; justify-content: center; } button { margin: 10px 5px; cursor: pointer; }
JavaScript 部分
实现节点生成、事件绑定逻辑,替换原有空的help()函数:
// 生成单条可编辑选项 function createOption() { const optionWrapper = document.createElement('div'); optionWrapper.className = 'option'; const optionText = document.createElement('div'); optionText.className = 'optionName'; optionText.contentEditable = true; optionText.innerText = 'Option'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'box'; optionWrapper.append(optionText, checkbox); return optionWrapper; } // 生成单个完整可编辑问题块 function createQuestion() { const questionWrapper = document.createElement('div'); questionWrapper.className = 'questionBlock'; // 可编辑问题名称 const questionName = document.createElement('div'); questionName.className = 'questionName'; questionName.contentEditable = true; questionName.innerText = 'Question'; // 选项存放容器 const optionList = document.createElement('div'); optionList.className = 'optionList'; // 每个问题默认自带1个选项 optionList.appendChild(createOption()); // 当前问题专属的新增选项按钮 const addOptionBtn = document.createElement('button'); addOptionBtn.type = 'button'; addOptionBtn.innerText = 'Add Option'; // 绑定事件:仅给当前问题新增选项 addOptionBtn.addEventListener('click', () => { optionList.appendChild(createOption()); }); questionWrapper.append(questionName, optionList, addOptionBtn); return questionWrapper; } // 页面加载完成后初始化 document.addEventListener('DOMContentLoaded', () => { const questionContainer = document.getElementById('questionContainer'); const addQuestionBtn = document.getElementById('addQuestionBtn'); // 默认渲染第一个问题 questionContainer.appendChild(createQuestion()); // 绑定全局新增问题事件 addQuestionBtn.addEventListener('click', () => { questionContainer.appendChild(createQuestion()); }); });
实现效果
- 所有问题名称、选项文本都保留点击直接编辑的能力
- 每个问题的「Add Option」按钮仅操作当前问题的选项列表,新增选项自带可编辑文本和多选框,支持添加任意数量选项
- 全局「Add Question」按钮可生成全新的独立问题块,每个问题的编辑、添加选项功能互不干扰
- 所有多选框支持独立勾选,无联动限制
内容的提问来源于stack exchange,提问作者Chris Costa
相关产品推荐
相关产品推荐

