当前位置:首页 > 技术 > 正文内容

深入解析Rich Text编辑器行内样式实现

访客 技术 2026年7月25日 2

在前一篇文章中,我们探讨了块级元素的格式化操作,本文将聚焦于行内元素(inline elements)的样式处理。行内样式通常包括加粗斜体代码片段删除线等。在Slate框架中,行内元素被称为"叶子"(leaf),通过renderLeaf属性进行渲染。

构建叶子组件

首先创建专门的叶子渲染组件文件 _leaf.jsx,用于处理不同行内样式:

export const Leaf = ({ attributes, children, leaf }) => {
    if (leaf.bold) {
        children = <strong>{children}</strong>
    }

    if (leaf.code) {
        children = <code>{children}</code>
    }

    if (leaf.italic) {
        children = <em>{children}</em>
    }

    if (leaf.underline) {
        children = <u>{children}</u>
    }

    return <span {...attributes}>{children}</span>
}

分离渲染逻辑

为了更好地组织代码,我们将叶子渲染器独立为 _leafRender.jsx

import React from 'react'
import { Leaf } from './_leaf'

export const renderLeaf = props => {
    return <Leaf {...props} />
}

同时整理块级元素渲染器到 _elementRender.jsx

import React from 'react';
import { CodeElement, DefaultElement } from './_elements';

export const renderElement = props => {
    switch (props.element.type) {
        case 'code':
            return <CodeElement {...props} />
        default:
            return <DefaultElement {...props} />
    }
}

整合编辑器核心

现在更新主组件 SDocer.jsx,引入独立渲染器并添加行内样式快捷键:

import { useState, useCallback } from 'react';
import { createEditor, Editor, Transforms, Element } from 'slate';
import { Slate, withReact, Editable } from 'slate-react';

import { initialValue } from './_configure';
import { renderElement } from './_elementRender';
import { renderLeaf } from './_leafRender';

function SDocer() {
  const [editor] = useState(() => withReact(createEditor()));

  return (
    <Slate editor={editor} initialValue={initialValue}>
      <Editable
        renderElement={useCallback(renderElement, [])}
        renderLeaf={useCallback(renderLeaf, [])}
        onKeyDown={event => {
          if (!event.ctrlKey) return;

          switch (event.key) {
            case '`': {
              event.preventDefault();
              const [match] = Editor.nodes(editor, {
                match: n => n.type === 'code',
              });
              Transforms.setNodes(
                editor,
                { type: match ? 'paragraph' : 'code' },
                { match: n => Element.isElement(n) && Editor.isBlock(editor, n) }
              );
              break;
            }

            case 'b': {
              event.preventDefault();
              Editor.addMark(editor, 'bold', true);
              break;
            }
          }
        }}
      />
    </Slate>
  );
}

export default SDocer;

初始化数据配置

更新 _configrue.jsx 以展示混合样式:

export const initialValue = [
    {
        type: 'paragraph',
        children: [{ text: '这是一行段落文字,内容很少,但很重要!!' }],
    },
    {
        type: 'code',
        children: [{ text: '这是一代码行段落文字,内容很少,但很重要!!' }],
    },
    {
        type: 'paragraph',
        children: [
            { text: 'This is editable ' },
            { text: 'rich', bold: true },
            { text: ' text, ' },
            { text: 'much', italic: true },
            { text: ' better than a ' },
            { text: '<textarea>', code: true, underline: true },
            { text: '<textarea>', underline: true },
            { text: '!' },
        ],
    },
];

通过上述实现,编辑器已经能够响应 Ctrl+B 快捷键进行加粗操作,同时保留了块级元素的格式切换功能。随着功能扩展,编辑器的能力也逐步增强。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。