辣鸡丝炒芋头
辣鸡丝炒芋头
  • 发布:2026-06-14 22:44
  • 更新:2026-06-14 22:44
  • 阅读:18

uni-app中app(安卓端实测)中<editor>组件光标使用按钮插入特定符号(如【】)时定位到特定字符中间的可行方案

分类:uni-app

uni-app app端(安卓实测)<editor>组件光标使用按钮插入特定符号(如【】)时定位到特定字符中间的可行方案

因为在做文本编辑器(符号快捷成对(如【】这种的)输入)需用到editor组件。
因为不能直接使用DOM,因网上搜不出解决方案,借助AI后实测出一种方案和一种待验证方案。
思路简单得离谱(主要还是对edtior这个组件不了解):

首先说一下editor

<editor> 组件底层是基于 Quill.js,所以不能使用原生输入框的 selectionStart/setSelectionRange。光标操作只能通过 Quill API 或标准 DOM API 实现。

方案一:Quill API(推荐这种)

获取 Quill 实例

const editor = document.getElementById('editor')  
const quill = editor.__quill || editor.querySelector('.ql-editor')?.__quill

核心示例:插入配对符号并定位光标

例如:一个按钮直接插入【】,你需要光标在【】的中间

const range = quill.getSelection()  
const pos = range ? range.index : 0  
const half = Math.ceil(pair.length / 2)  
quill.insertText(pos, pair)  
quill.setSelection(pos + half)

优缺点

优点

  • API 简洁高效
  • 与编辑器状态(Delta)完全同步
  • 不影响撤销/重做

缺点

  • 依赖 Quill 内部属性 __quill
  • 不同版本 uni-app 兼容性不确定
  • 需在 renderjs 中运行

方案二:原生 DOM API(降级方案:这个未验证,因为第一种方案基本解决,这是ai给的降级兜底方案)

核心思路

使用 document.createTreeWalker 遍历文本节点计算全局偏移,通过 Range + Selection API 操作光标。

获取光标全局偏移

function getCursorIndex(container) {  
    const sel = window.getSelection()  
    if (!sel?.rangeCount) return -1  
    const node = sel.anchorNode, off = sel.anchorOffset  
    if (!node || !container.contains(node)) return -1  
    const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT)  
    let count = 0  
    while (walker.nextNode()) {  
        if (walker.currentNode === node) return count + off  
        count += walker.currentNode.textContent.length  
    }  
    return count  
}

设置光标到指定位置

function setCursorIndex(container, index) {  
    const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT)  
    let count = 0  
    while (walker.nextNode()) {  
        const len = walker.currentNode.textContent.length  
        if (count + len >= index) {  
            const range = document.createRange()  
            range.setStart(walker.currentNode, index - count)  
            range.collapse(true)  
            const sel = window.getSelection()  
            sel.removeAllRanges()  
            sel.addRange(range)  
            return  
        }  
        count += len  
    }  
}

插入文本并设置光标

const text = foundNode.textContent  
foundNode.textContent = text.slice(0, offset) + pair + text.slice(offset)  
const range = document.createRange()  
range.setStart(foundNode, offset + half)  
range.collapse(true)  
window.getSelection().removeAllRanges()  
window.getSelection().addRange(range)

优缺点

优点

  • 纯标准 DOM API,兼容性最好
  • 不依赖任何框架内部属性

缺点

  • 代码较复杂
  • 直接改 textContent 可能破坏 Quill Delta 同步
  • 富文本元素(图片等)偏移计算需额外处理

两种方案对比

代码量

  • Quill API:3 行
  • DOM API:30+ 行
  • Delta 同步

  • Quill API:✅ 完全同步
  • DOM API:❌ 可能不同步

撤销/重做

  • Quill API:✅ 正常
  • DOM API:❌ 可能受影响

WebView 兼容性

  • Quill API:⭐⭐⭐(依赖 Quill 版本)
  • DOM API:⭐⭐⭐⭐⭐

uni-app App 端实践要点

  • 逻辑层无 DOM,所有 DOM 操作必须通过 renderjs 执行
  • renderjs 通过 change:prop 模板绑定接收逻辑层数据,通过 ownerVm.callMethod() 回传状态
  • 方法签名:methodName(newVal, oldVal, ownerVm, vm)
  • 推荐双方案:优先 Quill API → 失败则降级 DOM API
0 关注 分享

要回复文章请先登录注册