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

CKEditor5中无法为链接添加title属性的问题求助

解决CKEditor5 React版添加链接title属性问题

核心思路

CKEditor5采用模型-视图分离架构,不能直接沿用CKEditor4的extraAllowedContent配置,必须通过扩展Schema允许属性 + 配置双向转换规则 + 扩展UI支持输入title三步实现需求。

步骤1:创建自定义插件扩展链接功能

新建LinkTitlePlugin.js,用来扩展链接的Schema、转换逻辑,同时给链接编辑表单添加title输入项:

import { Plugin } from '@ckeditor/ckeditor5-core';
import { Link, LinkUI } from '@ckeditor/ckeditor5-link';
import { FieldView } from '@ckeditor/ckeditor5-ui/src/field';

export default class LinkTitlePlugin extends Plugin {
  static get requires() {
    return [Link, LinkUI];
  }

  init() {
    const editor = this.editor;
    const schema = editor.model.schema;
    const conversion = editor.conversion;
    const linkUI = editor.plugins.get(LinkUI);

    // 1. 扩展Schema:允许文本节点拥有linkTitle属性
    schema.extend('$text', {
      allowAttributes: 'linkTitle'
    });

    // 2. 视图→模型转换:从<a title="xxx">提取title到模型的linkTitle属性
    conversion.for('upcast').attributeToAttribute({
      view: {
        name: 'a',
        key: 'title'
      },
      model: 'linkTitle'
    });

    // 3. 模型→视图转换:将模型的linkTitle属性映射到<a>的title属性
    conversion.for('downcast').attributeToAttribute({
      model: 'linkTitle',
      view: 'title'
    });

    // 4. 扩展链接编辑表单,添加title输入框
    linkUI.on('open', () => {
      const form = linkUI.formView;
      const currentTitle = editor.model.document.selection.getAttribute('linkTitle') || '';

      // 创建title输入字段
      const titleFieldView = editor.ui.componentFactory.create('textInput');
      titleFieldView.label = '链接标题';
      titleFieldView.value = currentTitle;

      const titleField = new FieldView(editor.locale);
      titleField.children.add(titleFieldView);
      form.children.add(titleField);

      // 提交表单时更新模型的linkTitle属性
      form.on('submit', () => {
        const titleValue = titleFieldView.element.value.trim();
        editor.model.change(writer => {
          const selection = editor.model.document.selection;
          if (titleValue) {
            writer.setAttribute('linkTitle', titleValue, selection.getFirstPosition());
          } else {
            writer.removeAttribute('linkTitle', selection.getFirstPosition());
          }
        });
      });
    });
  }
}

步骤2:在React组件中配置CKEditor

引入自定义插件并完成编辑器配置:

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import Link from '@ckeditor/ckeditor5-link/src/link';
import LinkTitlePlugin from './LinkTitlePlugin';

export default function EditorComponent() {
  return (
    <CKEditor
      editor={ClassicEditor}
      config={{
        plugins: [Link, LinkTitlePlugin, /* 其他必填插件:比如Essentials、Paragraph等 */],
        toolbar: ['link', /* 其他需要的工具栏按钮 */]
      }}
      data="<p><a href='https://example.com' title='示例链接'>点击跳转</a></p>"
      onChange={(event, editor) => {
        console.log('输出带title的HTML:', editor.getData());
      }}
    />
  );
}

常见问题说明

  • 之前方法无效的原因:
    • extraAllowedContent是CKEditor4的语法,CKEditor5不支持,必须用Schema和转换规则实现属性管控
    • 链接装饰器是用来处理target="_blank"这类开关型属性的,不适合添加需要用户输入的自定义属性
    • 扩展Schema时要给$text节点添加属性,因为链接是直接应用在文本内容上的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:12:44