Draft.js 如何为图片添加超链接?现有文本加链接方法不适配图片场景
Draft.js为图片添加超链接的实现方案
问题原因
现有代码的触发逻辑依赖!selection.isCollapsed()非折叠选区判断,而Draft.js中图片作为atomic类型的原子块,被点击/选中时选区默认是折叠状态,因此原有逻辑不会触发。
解决方案步骤
第一步:修改触发逻辑,兼容图片选中场景
在原有判断基础上,补充选中原子块的校验逻辑即可,示例代码如下:
const selection = state.editorState.getSelection(); const contentState = state.editorState.getCurrentContent(); // 原有文本选区逻辑 + 选中原子块的逻辑 const isTextSelection = !selection.isCollapsed(); const selectedBlock = contentState.getBlockForKey(selection.getStartKey()); const isImageBlockSelected = selectedBlock.getType() === 'atomic' && selectedBlock.getEntityAt(0) // 此处替换为你自己定义的图片实体类型名 && contentState.getEntity(selectedBlock.getEntityAt(0)).getType() === 'IMAGE'; if (isTextSelection || isImageBlockSelected) { let url = ''; if (isTextSelection) { // 保留原有文本链接的读取逻辑 const linkKey = selectedBlock.getEntityAt(selection.getStartOffset()); if (linkKey) { const linkInstance = contentState.getEntity(linkKey); url = linkInstance.getData().url; } } else { // 读取图片上已绑定的链接地址 const imageEntity = contentState.getEntity(selectedBlock.getEntityAt(0)); url = imageEntity.getData().linkUrl || ''; } setState((prevState) => ({ ...prevState, showUrlModal: true, urlValue: url, })); }
第二步:提交链接时绑定到图片实体
用户在弹窗输入链接确认后,区分文本和图片场景分别处理:
- 文本场景保留原有创建LINK实体的逻辑
- 图片场景需要更新原有图片实体,把链接地址存入实体的
data中,示例:
// 提交链接时的处理逻辑 const handleUrlSubmit = (inputUrl) => { const selection = state.editorState.getSelection(); const contentState = state.editorState.getCurrentContent(); const selectedBlock = contentState.getBlockForKey(selection.getStartKey()); const isImageBlock = selectedBlock.getType() === 'atomic' && selectedBlock.getEntityAt(0) && contentState.getEntity(selectedBlock.getEntityAt(0)).getType() === 'IMAGE'; let newEditorState; if (isImageBlock) { // 给原有图片实体补充linkUrl属性 const newContentState = contentState.mergeEntityData( selectedBlock.getEntityAt(0), { linkUrl: inputUrl } ); newEditorState = EditorState.push(state.editorState, newContentState, 'apply-entity'); } else { // 原有给文本加LINK实体的逻辑 // ... } // 后续更新编辑器状态、关闭弹窗即可 }
第三步:修改图片渲染逻辑
在自定义的atomic块渲染函数中,判断图片实体是否有linkUrl属性,存在的话用<a>标签包裹图片:
// 原子块渲染示例 const atomicBlockRenderer = (block) => { if (block.getType() === 'atomic') { return { component: (props) => { const entity = props.contentState.getEntity(props.block.getEntityAt(0)); const { src, alt, linkUrl } = entity.getData(); const image = <img src={src} alt={alt} />; return linkUrl ? <a href={linkUrl} target="_blank" rel="noopener noreferrer">{image}</a> : image; }, editable: false }; } return null; }
内容的提问来源于stack exchange,提问作者Claudiu
相关产品推荐
相关产品推荐

