JavaScript开发调查问卷时如何选中当前问题div添加选项
问题根源
无参数调用newOption()时,原有逻辑固定选择DOM中第一个class为question的元素作为父容器,而新创建的问题是追加在问卷容器末尾的,自然无法匹配到最新创建的问题分组。
最小改动修复
直接把无参时取父节点的逻辑改成取question类元素集合的最后一项即可,新追加的节点永远在集合末尾:
function newOption(father) { if (arguments.length == 0) { const questionNodes = document.getElementsByClassName('question'); // 未创建任何问题时直接终止,避免脚本报错 if (questionNodes.length === 0) return; // 取集合最后一项,即最新创建的问题 var father = questionNodes[questionNodes.length - 1]; } // 后续原有逻辑保持不变 const op = document.createElement('div'); op.classList.add("option"); // 注意:原有代码里所有ul都用了id="optionList",id全局唯一,重复使用不符合规范,建议改成class op.innerHTML = '<div> <ul class="optionList"> <li class="optionName" contenteditable="true">Option <li class="box"> <input type="checkbox"> </li> </ul> </div>'; father.appendChild(op); }
更贴合面向对象思路的优化方案
如果想实现更灵活的交互(比如用户可以手动选择要给哪个问题加选项,而不是只能给最新的加),可以加全局状态维护当前选中的问题:
- 定义全局变量
currentQuestion存储当前激活的问题节点 - 新建问题时,自动把新问题设为当前激活项,给激活项加个明显的边框/背景高亮提示
- 给每个问题绑定点击事件,点击对应问题就切换激活状态
- 无参调用
newOption()时直接取currentQuestion作为父节点即可
对应核心实现代码参考:
// 全局存储当前激活的问题 let currentQuestion = null; // 页面初始化就创建第一个问题 newQuestion() function newQuestion() { const questionaire = document.getElementById('questionaire'); const question = document.createElement('div'); question.classList.add("question"); // 给问题绑定点击切换激活的事件 question.addEventListener('click', () => setActiveQuestion(question)) const qname = document.createElement('div'); qname.classList.add("qName"); qname.innerHTML = '<div contenteditable="true">Your Question</div>'; question.appendChild(qname); questionaire.append(question); // 新建的问题自动设为激活状态 setActiveQuestion(question) newOption(question) } // 抽离设置激活问题的方法 function setActiveQuestion(target) { // 先清除之前激活问题的高亮样式 if (currentQuestion) { currentQuestion.classList.remove('active'); } currentQuestion = target; // 给当前激活问题加高亮样式类,方便用户识别 currentQuestion.classList.add('active'); } function newOption(father) { if (arguments.length == 0) { // 没有激活问题时直接返回 if (!currentQuestion) return; var father = currentQuestion; } const op = document.createElement('div'); op.classList.add("option"); op.innerHTML = '<div> <ul class="optionList"> <li class="optionName" contenteditable="true">Option <li class="box"> <input type="checkbox"> </li> </ul> </div>'; father.appendChild(op); }
配套在CSS里添加激活态样式即可,比写内联样式更易维护:
.question.active { outline: 3px solid #ff6b00; }
内容的提问来源于stack exchange,提问作者Chris Costa
相关产品推荐
相关产品推荐

