You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不丢失文本选区的情况下为Slate-React实现超链接插入弹窗

核心解决思路是不依赖浏览器原生选区,提前存储Slate内部独立维护的选区状态,具体操作步骤如下:

  • 点击工具栏插入链接按钮、弹窗打开前,第一时间将当前editor.selection的值存入ref中,Slate的选区状态独立于浏览器原生逻辑,不会因为编辑器失焦被自动清空。
  • 给自定义弹窗的根元素绑定onMouseDown事件,回调中执行e.preventDefault(),可以阻止点击弹窗时触发编辑器的原生失焦逻辑,选中文本的高亮状态也会暂时保留,和Google Docs的交互效果一致。
  • 用户输入链接确认插入时,先调用Transforms.select(editor, 之前存储的选区)恢复编辑器选中状态,再执行链接节点的包裹逻辑即可正常插入。

如果需要在编辑器失焦后依然展示选中区域的高亮效果,可以通过Slate的decorate API,给落在存储选区范围内的文本节点添加自定义高亮样式,完全复刻Google Docs的交互表现。

参考实现代码:

import { Transforms, Editor } from 'slate'
import { useRef, useState } from 'react'
import { useSlate, Editable } from 'slate-react'

// 编辑器组件内逻辑
const RichEditor = () => {
  const [editor] = useSlate()
  const [linkModalOpen, setLinkModalOpen] = useState(false)
  // 存储选区的ref,重渲染不会丢失值
  const savedSelectionRef = useRef(null)

  // 点击插入链接按钮的回调
  const handleLinkBtnClick = () => {
    savedSelectionRef.current = editor.selection
    setLinkModalOpen(true)
  }

  // 弹窗确认插入链接的回调
  const handleLinkConfirm = (inputUrl) => {
    if (!savedSelectionRef.current || !inputUrl) return
    // 恢复之前保存的选区
    Transforms.select(editor, savedSelectionRef.current)
    // 构造链接节点插入
    const linkNode = {
      type: 'link',
      url: inputUrl,
      children: [{ text: Editor.string(editor, savedSelectionRef.current) }]
    }
    Transforms.wrapNodes(editor, linkNode, { split: true })
    // 重置状态
    savedSelectionRef.current = null
    setLinkModalOpen(false)
  }

  return (
    <div>
      {/* 编辑器工具栏 */}
      <button onClick={handleLinkBtnClick}>插入超链接</button>
      {/* 编辑器主体 */}
      <Editable placeholder="请输入内容" />
      {/* 自定义弹窗 */}
      {linkModalOpen && (
        <div 
          className="link-modal"
          // 阻止mousedown默认行为,避免编辑器失焦
          onMouseDown={(e) => e.preventDefault()}
        >
          <input type="text" placeholder="请输入链接地址" />
          <button onClick={(e) => handleLinkConfirm(e.target.previousSibling.value)}>确认</button>
        </div>
      )}
    </div>
  )
}

内容的提问来源于stack exchange,提问作者Dorian Fabre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:15:02