如何将WordPress Gutenberg Popover定位到光标位置?
要实现Popover定位到RichText光标位置,同时适配全站点编辑器并替换弃用的getAnchorRect,可以通过以下方式使用最新的anchor属性:
核心修改要点
- 弃用全局变量存储选区,改用React状态管理,避免全站点编辑器多实例冲突
- 直接将选区的
Range对象传给Popover的anchor属性(WordPress的Popover组件支持Range作为anchor参数) - 优化选区获取逻辑,确保在全站点编辑器环境下也能正确获取光标位置
修改后的完整代码
import { registerFormatType, toggleFormat } from '@wordpress/rich-text'; import { Fragment, useState } from '@wordpress/element'; import { BlockControls, RichTextShortcut } from '@wordpress/block-editor'; import { Popover, ToolbarButton, ToolbarGroup } from '@wordpress/components'; import { displayShortcut } from '@wordpress/keycodes'; import { __ } from '@wordpress/i18n'; const InsertMyPopup = { name: 'insertmypopup', title: __('My Popup'), character: 'o', value: '', }; const { name, title, character } = InsertMyPopup; const type = `my-popup/${name}`; registerFormatType(type, { title, tagName: name, className: null, active: false, edit({ isActive, value, onChange, contentRef }) { // 使用状态存储选区Range,替代全局变量 const [ anchorRange, setAnchorRange ] = useState(null); const onToggle = () => { // 获取当前选区 const selection = document.defaultView.getSelection(); const currentRange = selection.rangeCount > 0 ? selection.getRangeAt(0) : null; // 保存选区到状态 setAnchorRange(currentRange); onChange(toggleFormat(value, { type })); }; const thePopover = isActive && anchorRange && ( <Popover placement='bottom-start' focusOnMount='firstElement' key='my-popover' expandOnMobile={true} headerTitle={__( 'My Popup', 'insert-my-popup' )} onClose={() => { onChange(toggleFormat(value, { type })); setAnchorRange(null); }} // 使用最新的anchor属性,直接传入Range对象 anchor={anchorRange} > Popup </Popover> ); return ( <Fragment> <BlockControls group='other'> <ToolbarGroup> <ToolbarButton icon='editor-customchar' isPressed={isActive} label={title} onClick={onToggle} shortcut={displayShortcut.primary(character)} /> </ToolbarGroup> </BlockControls> <RichTextShortcut type='primary' character={character} onUse={onToggle} contentRef={contentRef} /> {thePopover} </Fragment> ); }, });
关键说明
- 状态管理替代全局变量:原来的全局
anchorRange在全站点编辑器多块/多实例场景下会出现状态混乱,改用useState存储当前组件的选区,保证隔离性。 - 直接使用Range作为anchor:WordPress的Popover组件支持将
Range对象作为anchor参数,内部会自动处理定位,比手动计算getBoundingClientRect更可靠,适配不同编辑器环境。 - 关闭弹窗时清空状态:在Popover的
onClose回调中重置anchorRange,避免弹窗关闭后状态残留导致的异常。
内容的提问来源于stack exchange,提问作者Ben Marshall
相关产品推荐
相关产品推荐

