源码获取
私信回复题目拖拽获取完整源码
演示效果

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> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link href="css.css" rel="stylesheet" /></head><body> <div class="header"> <h1><i class="fas fa-poll"></i>拖拽式出题效果</h1> <p>从左侧拖拽题目类型到右侧编辑区,自由构建您的问卷。点击题目可进行编辑,拖拽题目可调整顺序。</p> </div> <div class="container"> <!-- 左侧工具栏 --> <div class="toolbar"> <h2><i class="fas fa-toolbox"></i> 题目类型</h2> <div class="question-types"> <div class="question-type" draggable="true" data-type="single-choice"> <i class="far fa-dot-circle"></i> <span>单选题</span> <div class="desc">拖拽添加</div> </div> <div class="question-type" draggable="true" data-type="multiple-choice"> <i class="far fa-check-square"></i> <span>多选题</span> <div class="desc">拖拽添加</div> </div> <div class="question-type" draggable="true" data-type="text"> <i class="fas fa-font"></i> <span>文本题</span> <div class="desc">拖拽添加</div> </div> </div> <div class="drag-hint"> <i class="fas fa-mouse-pointer"></i> 拖拽题目类型到右侧区域 </div> </div> <!-- 右侧编辑区 --> <div class="editor"> <div class="editor-header"> <h2><i class="fas fa-edit"></i> 问卷编辑区</h2> <div class="question-count">题目数量: <span id="question-count">0</span></div> </div> <div class="questions-container" id="questions-container"> <!-- 初始空状态 --> <div class="empty-state" id="empty-state"> <i class="fas fa-inbox"></i> <h3>问卷内容为空</h3> <p>从左侧拖拽题目类型到这里开始创建问卷,或点击下方按钮添加示例题目。</p> </div> </div> <div class="actions"> <button class="btn btn-secondary" id="add-sample"> <i class="fas fa-plus-circle"></i> 添加示例题目 </button> <button class="btn btn-primary" id="preview"> <i class="fas fa-eye"></i> 预览问卷 </button> </div> </div> </div> <script src="js.js"></script></body></html>css 文件
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Segoe UI", "Microsoft YaHei", sans-serif;}body { background-color: #f5f7fa; color: #333; line-height: 1.6; padding: 20px;}.container { display: flex; max-width: 1400px; margin: 0 auto; gap: 20px;}.header { text-align: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #e0e6ef;}.header h1 { color: #2c3e50; margin-bottom: 10px; font-size: 2.2rem;}.header p { color: #7f8c8d; max-width: 800px; margin: 0 auto;}/* 左侧工具栏样式 */.toolbar { width: 280px; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); padding: 20px; height: fit-content; position: sticky; top: 20px;}.toolbar h2 { color: #2c3e50; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #eee; font-size: 1.4rem;}.question-types { display: flex; flex-direction: column; gap: 12px;}.question-type { display: flex; align-items: center; padding: 14px 16px; background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; cursor: grab; transition: all 0.2s ease; user-select: none;}.question-type:hover { background-color: #edf2f7; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);}.question-type:active { cursor: grabbing; transform: translateY(0);}.question-type i { font-size: 1.2rem; color: #4a6cf7; margin-right: 12px; width: 24px; text-align: center;}.question-type span { font-weight: 500; color: #2d3748;}.question-type .desc { font-size: 0.85rem; color: #718096; margin-left: auto;}/* 右侧编辑区样式 */.editor { flex: 1; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); padding: 30px;}.editor-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #eee;}.editor-header h2 { color: #2c3e50; font-size: 1.6rem;}.question-count { background-color: #4a6cf7; color: white; padding: 6px 14px; border-radius: 20px; font-size: 0.9rem; font-weight: 500;}.questions-container { min-height: 500px; padding: 10px; transition: all 0.3s ease;}.question-item { background-color: white; border: 1px solid #e2e8f0; border-radius: 10px; padding: 22px; margin-bottom: 20px; cursor: move; transition: all 0.3s ease; position: relative;}.question-item:hover { border-color: #cbd5e0; box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);}.question-item.dragging { opacity: 0.7; transform: rotate(3deg); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);}.question-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;}.question-title { font-size: 1.2rem; font-weight: 600; color: #2d3748; flex: 1; margin-right: 15px;}.question-title.editing { border: 1px solid #4a6cf7; padding: 8px 12px; border-radius: 6px; background-color: #f7f9ff;}.question-controls { display: flex; gap: 12px;}.question-controls button { background: none; border: none; color: #718096; cursor: pointer; font-size: 1.1rem; transition: color 0.2s; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 4px;}.question-controls button:hover { color: #4a6cf7; background-color: #f7f9ff;}.question-type-label { display: inline-block; background-color: #e8edff; color: #4a6cf7; font-size: 0.8rem; padding: 4px 10px; border-radius: 12px; margin-bottom: 15px; font-weight: 500;}.question-options { margin-top: 15px; padding-left: 5px;}.option-item { display: flex; align-items: center; margin-bottom: 12px;}.option-item input[type="radio"],.option-item input[type="checkbox"] { margin-right: 12px;}.option-item input[type="text"] { flex: 1; padding: 10px 14px; border: 1px solid #e2e8f0; border-radius: 6px; font-size: 1rem; transition: border 0.2s;}.option-item input[type="text"]:focus { border-color: #4a6cf7; outline: none;}.option-item .remove-option { margin-left: 10px; color: #a0aec0; cursor: pointer; font-size: 1.2rem; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border-radius: 4px;}.option-item .remove-option:hover { color: #e53e3e; background-color: #fff5f5;}.add-option { margin-top: 10px; display: inline-flex; align-items: center; color: #4a6cf7; cursor: pointer; font-weight: 500; padding: 8px 12px; border-radius: 6px; transition: background-color 0.2s;}.add-option:hover { background-color: #f7f9ff;}.add-option i { margin-right: 8px; font-size: 0.9rem;}.empty-state { text-align: center; padding: 60px 20px; color: #a0aec0;}.empty-state i { font-size: 4rem; margin-bottom: 20px; color: #e2e8f0;}.empty-state h3 { font-size: 1.5rem; margin-bottom: 10px; color: #718096;}.empty-state p { max-width: 500px; margin: 0 auto;}.drag-hint { display: flex; align-items: center; justify-content: center; margin-top: 30px; color: #a0aec0; font-size: 0.9rem;}.drag-hint i { margin-right: 8px;}/* 响应式设计 */@media (max-width: 1024px) { .container { flex-direction: column; } .toolbar { width: 100%; position: static; margin-bottom: 20px; } .question-types { flex-direction: row; flex-wrap: wrap; } .question-type { width: calc(50% - 6px); }}@media (max-width: 768px) { .question-type { width: 100%; } .question-controls { gap: 8px; } .editor { padding: 20px; }}/* 拖拽区域样式 */.drop-zone { border: 2px dashed #cbd5e0; border-radius: 10px; padding: 30px; text-align: center; margin-bottom: 20px; color: #a0aec0; transition: all 0.3s ease;}.drop-zone.active { border-color: #4a6cf7; background-color: rgba(74, 108, 247, 0.05); color: #4a6cf7;}.question-item.placeholder { border: 2px dashed #4a6cf7; background-color: rgba(74, 108, 247, 0.05); height: 120px; display: flex; align-items: center; justify-content: center; color: #4a6cf7;}.question-item.placeholder i { margin-right: 10px;}/* 底部操作栏 */.actions { display: flex; justify-content: flex-end; margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee;}.btn { padding: 12px 28px; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-size: 1rem; border: none;}.btn-primary { background-color: #4a6cf7; color: white;}.btn-primary:hover { background-color: #3a5ce5; transform: translateY(-2px); box-shadow: 0 6px 12px rgba(74, 108, 247, 0.2);}.btn-secondary { background-color: #edf2f7; color: #4a5568; margin-right: 15px;}.btn-secondary:hover { background-color: #e2e8f0;}/* 预览页面样式 */.preview-container { max-width: 800px; margin: 0 auto; padding: 30px; background-color: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);}.preview-header { text-align: center; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 1px solid #e0e6ef;}.preview-header h1 { color: #2c3e50; margin-bottom: 10px;}.preview-header p { color: #7f8c8d;}.preview-question { margin-bottom: 30px; padding: 20px; border: 1px solid #e2e8f0; border-radius: 10px; background-color: #f8fafc;}.preview-question-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 15px; color: #2d3748;}.preview-option { display: flex; align-items: center; margin-bottom: 10px; padding: 10px; background-color: white; border-radius: 6px; border: 1px solid #e2e8f0;}.preview-option input[type="radio"],.preview-option input[type="checkbox"] { margin-right: 12px;}.preview-text-input { width: 100%; padding: 12px 16px; border: 1px solid #e2e8f0; border-radius: 6px; font-size: 1rem;}.preview-text-input:focus { border-color: #4a6cf7; outline: none;}.back-btn { display: inline-block; margin-top: 30px; padding: 10px 20px; background-color: #4a6cf7; color: white; text-decoration: none; border-radius: 6px; font-weight: 500;}.back-btn:hover { background-color: #3a5ce5;}.required-badge { color: #e53e3e; font-size: 0.9rem; margin-left: 5px;}js 文件
// 题目数据let questions = [];let questionIdCounter = 1;let editingQuestionId = null;// DOM元素const questionsContainer = document.getElementById('questions-container');const emptyState = document.getElementById('empty-state');const questionCountElement = document.getElementById('question-count');const addSampleBtn = document.getElementById('add-sample');const previewBtn = document.getElementById('preview');// 题目类型配置(仅保留三种)const questionTypes = { 'single-choice': { name: '单选题', icon: 'far fa-dot-circle', options: ['选项1', '选项2', '选项3'] }, 'multiple-choice': { name: '多选题', icon: 'far fa-check-square', options: ['选项1', '选项2', '选项3', '选项4'] }, 'text': { name: '文本题', icon: 'fas fa-font', options: [] }};// 初始化拖拽功能function initDragAndDrop() { // 题目类型拖拽 const questionTypes = document.querySelectorAll('.question-type'); questionTypes.forEach(type => { type.addEventListener('dragstart', handleDragStart); }); // 编辑区域拖拽事件 questionsContainer.addEventListener('dragover', handleDragOver); questionsContainer.addEventListener('dragenter', handleDragEnter); questionsContainer.addEventListener('dragleave', handleDragLeave); questionsContainer.addEventListener('drop', handleDrop); // 题目排序拖拽事件监听 questionsContainer.addEventListener('dragstart', handleQuestionDragStart); questionsContainer.addEventListener('dragend', handleQuestionDragEnd);}// 处理题目类型拖拽开始function handleDragStart(e) { e.dataTransfer.setData('text/plain', e.target.dataset.type); e.dataTransfer.effectAllowed = 'copy';}// 处理编辑区域拖拽悬停function handleDragOver(e) { e.preventDefault(); // 区分是题目类型拖拽还是题目排序拖拽 if (e.target.closest('.question-item')) { e.dataTransfer.dropEffect = 'move'; } else { e.dataTransfer.dropEffect = 'copy'; } // 处理题目排序的拖拽位置 const draggedQuestion = document.querySelector('.question-item.dragging'); if (draggedQuestion && e.target.closest('.question-item') && e.target.closest('.question-item') !== draggedQuestion) { const targetQuestion = e.target.closest('.question-item'); const rect = targetQuestion.getBoundingClientRect(); const y = e.clientY - rect.top; const halfHeight = rect.height / 2; if (y < halfHeight) { questionsContainer.insertBefore(draggedQuestion, targetQuestion); } else { questionsContainer.insertBefore(draggedQuestion, targetQuestion.nextSibling); } }}function handleDragEnter(e) { if (e.target.classList.contains('questions-container')) { e.target.classList.add('active'); }}function handleDragLeave(e) { if (e.target.classList.contains('questions-container')) { e.target.classList.remove('active'); }}// 处理题目类型放置和题目排序function handleDrop(e) { e.preventDefault(); questionsContainer.classList.remove('active'); const questionType = e.dataTransfer.getData('text/plain'); if (questionType) { // 如果是从左侧拖拽题目类型到编辑区 addQuestion(questionType); } else { // 如果是在编辑区内拖拽题目排序 updateQuestionsOrder(); }}// 处理题目拖拽开始function handleQuestionDragStart(e) { if (e.target.closest('.question-item')) { const questionItem = e.target.closest('.question-item'); questionItem.classList.add('dragging'); e.dataTransfer.effectAllowed = 'move'; }}// 处理题目拖拽结束function handleQuestionDragEnd(e) { const draggingQuestion = document.querySelector('.question-item.dragging'); if (draggingQuestion) { draggingQuestion.classList.remove('dragging'); }}// 更新问题数组顺序function updateQuestionsOrder() { const questionElements = questionsContainer.querySelectorAll('.question-item'); const newQuestions = []; questionElements.forEach(element => { const questionId = parseInt(element.dataset.id); const question = questions.find(q => q.id === questionId); if (question) { newQuestions.push(question); } }); questions = newQuestions; renderQuestions();}// 添加题目function addQuestion(type) { const question = { id: questionIdCounter++, type: type, title: `${questionTypes[type].name} ${questions.length + 1}`, options: [...questionTypes[type].options], required: false }; questions.push(question); renderQuestions(); // 如果有空状态,移除它 if (questions.length === 1 && emptyState.parentNode) { emptyState.remove(); }}// 添加示例题目function addSampleQuestions() { const sampleTypes = ['single-choice', 'multiple-choice', 'text']; sampleTypes.forEach(type => { const question = { id: questionIdCounter++, type: type, title: `${questionTypes[type].name}示例`, options: [...questionTypes[type].options], required: Math.random() > 0.5 }; questions.push(question); }); renderQuestions(); // 如果有空状态,移除它 if (questions.length > 0 && emptyState.parentNode) { emptyState.remove(); }}// 删除题目function deleteQuestion(id) { const index = questions.findIndex(q => q.id === id); if (index !== -1) { questions.splice(index, 1); renderQuestions(); // 如果没有题目了,显示空状态 if (questions.length === 0 && !emptyState.parentNode) { questionsContainer.appendChild(emptyState); } }}// 开始编辑题目function startEditQuestion(id) { editingQuestionId = id; renderQuestions(); // 将焦点设置到标题输入框 const titleInput = document.getElementById(`question-title-${id}`); if (titleInput) { titleInput.focus(); titleInput.select(); }}// 完成编辑题目function finishEditQuestion(id) { const question = questions.find(q => q.id === id); if (!question) return; // 更新标题 const titleInput = document.getElementById(`question-title-${id}`); if (titleInput) { question.title = titleInput.value.trim() || question.title; } // 更新选项 if (question.type !== 'text') { const optionInputs = document.querySelectorAll(`#question-${id} .option-item input[type="text"]`); question.options = Array.from(optionInputs).map(input => input.value.trim()).filter(val => val); } editingQuestionId = null; renderQuestions();}// 添加选项function addOption(questionId) { const question = questions.find(q => q.id === questionId); if (question && question.type !== 'text') { question.options.push(`选项 ${question.options.length + 1}`); renderQuestions(); }}// 删除选项function deleteOption(questionId, optionIndex) { const question = questions.find(q => q.id === questionId); if (question && question.options.length > 1) { question.options.splice(optionIndex, 1); renderQuestions(); }}// 切换必填状态function toggleRequired(questionId) { const question = questions.find(q => q.id === questionId); if (question) { question.required = !question.required; renderQuestions(); }}// 渲染题目function renderQuestions() { // 清空容器 while (questionsContainer.firstChild) { questionsContainer.removeChild(questionsContainer.firstChild); } if (questions.length === 0) { questionsContainer.appendChild(emptyState); } else { questions.forEach((question, index) => { const questionElement = createQuestionElement(question, index); questionsContainer.appendChild(questionElement); }); } // 更新题目计数 questionCountElement.textContent = questions.length;}// 创建题目元素function createQuestionElement(question, index) { const isEditing = editingQuestionId === question.id; const typeInfo = questionTypes[question.type]; const questionElement = document.createElement('div'); questionElement.className = 'question-item'; questionElement.id = `question-${question.id}`; questionElement.draggable = true; questionElement.dataset.id = question.id; // 题目类型标签 const typeLabel = `<div class="question-type-label"><i class="${typeInfo.icon}"></i> ${typeInfo.name}</div>`; // 题目标题 let titleHtml; if (isEditing) { titleHtml = `<input type="text" id="question-title-${question.id}" class="question-title editing" value="${question.title}">`; } else { titleHtml = `<div class="question-title">${index + 1}. ${question.title} ${question.required ? '<span class="required-badge">(必填)</span>' : ''}</div>`; } // 题目控制按钮 let controlsHtml; if (isEditing) { controlsHtml = ` <div class="question-controls"> <button onclick="finishEditQuestion(${question.id})" title="完成编辑"> <i class="fas fa-check"></i> </button> <button onclick="toggleRequired(${question.id})" title="${question.required ? '取消必填' : '设为必填'}"> <i class="fas ${question.required ? 'fa-star' : 'fa-star-o'}"></i> </button> <button onclick="deleteQuestion(${question.id})" title="删除题目"> <i class="fas fa-trash"></i> </button> </div> `; } else { controlsHtml = ` <div class="question-controls"> <button onclick="startEditQuestion(${question.id})" title="编辑题目"> <i class="fas fa-edit"></i> </button> <button onclick="toggleRequired(${question.id})" title="${question.required ? '取消必填' : '设为必填'}"> <i class="fas ${question.required ? 'fa-star' : 'fa-star-o'}"></i> </button> <button onclick="deleteQuestion(${question.id})" title="删除题目"> <i class="fas fa-trash"></i> </button> <button title="拖拽排序" class="drag-handle"> <i class="fas fa-arrows-alt"></i> </button> </div> `; } // 题目选项 let optionsHtml = ''; if (question.type === 'text') { optionsHtml = ` <div class="question-options"> <div class="option-item"> <input type="text" placeholder="请输入文本答案..." disabled> </div> </div> `; } else { const inputType = question.type === 'single-choice' ? 'radio' : 'checkbox'; optionsHtml = ` <div class="question-options"> ${question.options.map((option, optionIndex) => ` <div class="option-item"> <input type="${inputType}" name="question-${question.id}" ${isEditing ? 'disabled' : ''}> ${isEditing ? `<input type="text" value="${option}"> <span class="remove-option" onclick="deleteOption(${question.id}, ${optionIndex})"> <i class="fas fa-times"></i> </span>` : `<span>${option}</span>` } </div> `).join('')} ${isEditing ? `<div class="add-option" onclick="addOption(${question.id})"> <i class="fas fa-plus"></i> 添加选项 </div>` : '' } </div> `; } questionElement.innerHTML = ` <div class="question-header"> ${titleHtml} ${controlsHtml} </div> ${typeLabel} ${optionsHtml} `; return questionElement;}// 生成预览页面function generatePreviewPage() { if (questions.length === 0) { alert('请先添加题目到问卷中!'); return; } // 创建预览HTML let previewHTML = ` <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>问卷预览 - 高仿问卷网</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> body { font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif; background-color: #f5f7fa; color: #333; padding: 20px; line-height: 1.6; } .preview-container { max-width: 800px; margin: 0 auto; padding: 30px; background-color: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); } .preview-header { text-align: center; margin-bottom: 40px; padding-bottom: 20px; border-bottom: 1px solid #e0e6ef; } .preview-header h1 { color: #2c3e50; margin-bottom: 10px; } .preview-header p { color: #7f8c8d; } .preview-question { margin-bottom: 30px; padding: 20px; border: 1px solid #e2e8f0; border-radius: 10px; background-color: #f8fafc; } .preview-question-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 15px; color: #2d3748; } .preview-option { display: flex; align-items: center; margin-bottom: 10px; padding: 10px; background-color: white; border-radius: 6px; border: 1px solid #e2e8f0; } .preview-option input[type="radio"], .preview-option input[type="checkbox"] { margin-right: 12px; } .preview-text-input { width: 100%; padding: 12px 16px; border: 1px solid #e2e8f0; border-radius: 6px; font-size: 1rem; } .preview-text-input:focus { border-color: #4a6cf7; outline: none; } .back-btn { display: inline-block; margin-top: 30px; padding: 10px 20px; background-color: #4a6cf7; color: white; text-decoration: none; border-radius: 6px; font-weight: 500; } .back-btn:hover { background-color: #3a5ce5; } .required-badge { color: #e53e3e; font-size: 0.9rem; margin-left: 5px; } .question-type-badge { display: inline-block; background-color: #e8edff; color: #4a6cf7; font-size: 0.8rem; padding: 4px 10px; border-radius: 12px; margin-left: 10px; font-weight: 500; } </style> </head> <body> <div class="preview-container"> <div class="preview-header"> <h1><i class="fas fa-poll"></i> 问卷预览</h1> <p>以下是您创建的问卷预览,共 ${questions.length}道题目</p> </div> `; // 添加题目预览 questions.forEach((question, index) => { previewHTML += ` <div class="preview-question"> <div class="preview-question-title"> ${index + 1}. ${question.title} ${question.required ? '<span class="required-badge">(必填)</span>' : ''} <span class="question-type-badge">${questionTypes[question.type].name}</span> </div> `; if (question.type === 'text') { previewHTML += ` <input type="text" class="preview-text-input" placeholder="请输入您的答案..." ${question.required ? 'required' : ''}> `; } else { const inputType = question.type === 'single-choice' ? 'radio' : 'checkbox'; question.options.forEach((option, optionIndex) => { previewHTML += ` <div class="preview-option"> <input type="${inputType}" id="preview-q${question.id}-o${optionIndex}" name="q${question.id}" ${question.required ? 'required' : ''}> <label for="preview-q${question.id}-o${optionIndex}">${option}</label> </div> `; }); } previewHTML += `</div>`; }); // 添加返回按钮 previewHTML += ` <div style="text-align: center;"> <a href="javascript:window.close();" class="back-btn"> <i class="fas fa-arrow-left"></i> 返回编辑 </a> <button onclick="window.print()" class="back-btn" style="margin-left: 10px; background-color: #38a169;"> <i class="fas fa-print"></i> 打印问卷 </button> </div> </div> <script> // 打印功能 function printQuestionnaire() { window.print(); } <\/script> </body> </html> `; // 打开新窗口显示预览 const previewWindow = window.open('', '_blank'); previewWindow.document.write(previewHTML); previewWindow.document.close();}// 初始化document.addEventListener('DOMContentLoaded', function () { initDragAndDrop(); // 添加示例题目按钮事件 addSampleBtn.addEventListener('click', addSampleQuestions); // 预览按钮事件 previewBtn.addEventListener('click', generatePreviewPage); // 双击题目开始编辑 questionsContainer.addEventListener('dblclick', function (e) { const questionItem = e.target.closest('.question-item'); if (questionItem) { const questionId = parseInt(questionItem.dataset.id); if (!isNaN(questionId) && editingQuestionId !== questionId) { startEditQuestion(questionId); } } }); // 点击其他地方完成编辑 document.addEventListener('click', function (e) { if (editingQuestionId && !e.target.closest(`#question-${editingQuestionId}`)) { finishEditQuestion(editingQuestionId); } });});
夜雨聆风