Vue.js:contenteditable容器添加文本与下拉框后选中值获取异常
问题解决:contenteditable中下拉框选中值无法正确获取
问题分析
当前代码的核心问题是:dropdowns数组里的selectedOption仅在下拉框创建时初始化,后续用户修改下拉框选中项时,没有同步更新这个值;而getDataModel方法又依赖这个数组里的旧值,导致始终拿到第一个选项。另外,克隆DOM后匹配选项的逻辑完全没必要,直接从真实DOM的select元素取当前选中值更可靠。
修复方案
直接从DOM读取选中值(更简洁,避免数据与DOM同步的潜在问题):在getDataModel方法里,遍历页面上的select元素,直接获取每个元素的当前选中值,无需依赖dropdowns数组的存储。同时优化下拉框插入位置,实现光标处插入的需求。
以下是完整修改代码:
<template> <div> <div class="content-editable" contenteditable="true" @input="onInput" ref="contentEditable"></div> <button @click="addDropdown">Add Dropdown</button> <button @click="getDataModel">Get Data Model</button> <div>{{ dataModel }}</div> </div> </template> <script> export default { data() { return { content: '', dropdownOptions: ['Option 1', 'Option 2', 'Option 3'], dataModel: '', }; }, methods: { onInput(event) { this.content = event.target.innerHTML.replace(/<div><br><\/div>/g, ''); }, addDropdown() { const editableDiv = this.$refs.contentEditable; const dropdownSelect = document.createElement('select'); dropdownSelect.style.width = '100px'; this.dropdownOptions.forEach((option) => { const dropdownOption = document.createElement('option'); dropdownOption.value = option; dropdownOption.text = option; dropdownSelect.appendChild(dropdownOption); }); // 插入到光标所在位置 const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); range.deleteContents(); range.insertNode(dropdownSelect); // 将光标移动到下拉框后方 const newRange = document.createRange(); newRange.setStartAfter(dropdownSelect); newRange.collapse(true); selection.removeAllRanges(); selection.addRange(newRange); } else { editableDiv.appendChild(dropdownSelect); } }, getDataModel() { const editableDiv = this.$refs.contentEditable; const clonedDiv = editableDiv.cloneNode(true); const selectElements = clonedDiv.querySelectorAll('select'); selectElements.forEach(select => { // 直接获取当前选中的文本 const selectedText = select.options[select.selectedIndex].text; select.replaceWith(document.createTextNode(` ${selectedText}`)); }); this.dataModel = clonedDiv.textContent.trim(); }, }, }; </script> <style scoped> .content-editable { border: 1px solid #ccc; padding: 10px; min-height: 100px; margin-bottom: 10px; } /* 优化下拉框在contenteditable中的交互 */ .content-editable select { pointer-events: auto; } </style>
额外优化说明
- 实现了下拉框插入到光标位置的需求,替代原代码直接追加到末尾的逻辑
- 移除了无用的
dropdowns数组,减少不必要的状态维护 - 添加了下拉框交互样式优化,避免在contenteditable中出现光标异常问题
内容的提问来源于stack exchange,提问作者Shibbir
相关产品推荐
相关产品推荐

