手把手带你10分钟手撸一个简易的Markdown编辑器(三)

简介: 接上文。

六、工具栏


最后我们就再实现一下编辑器的工具栏部分的工具(加粗、斜体、有序列表等等),因为这几个工具的实现思路都一致,我们就拿 「「加粗」」 这个工具举例子,其余的就可以模仿着写出来了


加粗工具的实现思路:


  • 光标是否选中文字?


  • 是。将选中文字的两侧加上**


  • 否。在光标所在处添加文字**加粗文字**


动图效果演示:


630b7b57085ee8ff41f45bd041ae314f.jpg


import React, { useState, useRef, useEffect } from 'react'
import markdownIt from 'markdown-it'
import './theme/github-theme.css'  
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
const md = new markdownIt({
    highlight: function (code, language) {      
        if (language && hljs.getLanguage(language)) {
          try {
            return `<pre><code class="hljs language-${language}">` +
                   hljs.highlight(code, { language  }).value +
                   '</code></pre>';
          } catch (__) {}
        }
        return '<pre class="hljs"><code>' + md.utils.escapeHtml(code) + '</code></pre>';
    }
})
let scrolling: 0 | 1 | 2 = 0  
let scrollTimer;  
export default function MarkdownEdit() {
    const [htmlString, setHtmlString] = useState('')
    const [value, setValue] = useState('')   // 编辑区的文字内容
    const edit = useRef(null) 
    const show = useRef(null)  
    const handleScroll = (block: number, event) => {
        let { scrollHeight, scrollTop, clientHeight } = event.target
        let scale = scrollTop / (scrollHeight - clientHeight)  
        if(block === 1) {
            if(scrolling === 0) scrolling = 1;  
            if(scrolling === 2) return;    
            driveScroll(scale, showRef.current)  
        } else if(block === 2) {  
            if(scrolling === 0) scrolling = 2;
            if(scrolling === 1) return;    
            driveScroll(scale, editRef.current)
        }
    }
    // 驱动一个元素进行滚动
    const driveScroll = (scale: number, el: HTMLElement) => {
        let { scrollHeight, clientHeight } = el
        el.scrollTop = (scrollHeight - clientHeight) * scale  
        if(scrollTimer) clearTimeout(scrollTimer);
        scrollTimer = setTimeout(() => {
            scrolling = 0   
            clearTimeout(scrollTimer)
        }, 200)
    }
    // 加粗工具
    const addBlod = () => {
        // 获取编辑区光标的位置。未选中文字时:selectionStart === selectionEnd ;选中文字时:selectionStart < selectionEnd
        let { selectionStart, selectionEnd } = edit.current
        let newValue = selectionStart === selectionEnd
                        ? value.slice(0, start) + '**加粗文字**' + value.slice(end)
                        : value.slice(0, start) + '**' + value.slice(start, end) + '**' + value.slice(end)
        setValue(newValue)
    }
    useEffect(() => {
        // 编辑区内容改变,更新value的值,并同步渲染
        setHtmlString(md.render(value))
    }, [value])
    return (
        <div className="markdownEditConainer">
            <button onClick={addBlod}>加粗</button>   {/* 假设一个加粗的按钮 */}
            <textarea 
                className="edit" 
                ref={edit}
                onScroll={(e) => handleScroll(1, e)}
                onChange={(e) => setValue(e.target.value)}   // 直接修改value的值,useEffect会同步渲染展示区的内容
                value={value}
            />
            <div 
                className="show"
                id="write"
                ref={show}
                onScroll={(e) => handleScroll(2, e)}
                dangerouslySetInnerHTML={{ __html: htmlString }}
            />
        </div>
    )
}


借助这样的思路,就可以完成其它各种工具的实现了。


在我已经发布的markdown-editor-reactjs (opens new window)[8]中,已经完成了其它工具的实现,想要看代码的可以去源码里看


七、补充


为了保证包的体积足够小,我将「第三方依赖库」「markdown主题」「代码高亮主题」都通过外链的形式导入了


八、最后


一个简易版的markdown编辑器就实现了,大家可以手动尝试实现一下。后续我也会继续发一些教程,对这个编辑器的功能进行扩展


我将代码都上传到了 Github仓库 (opens new window)[9](希望大家点个⭐️ 「star」),后续扩展一下功能,并作为一个完整的组件发布到npm给大家使用,希望大家多多支持~(其实我已经悄悄发布,但因功能还不是太完善,就不先拿出来给大家使用了,这里简单放个npm包的地址 (opens new window)[10]

相关文章
|
11天前
|
Ubuntu Linux 测试技术
Linux系统之部署轻量级Markdown文本编辑器
【10月更文挑战第6天】Linux系统之部署轻量级Markdown文本编辑器
54 1
Linux系统之部署轻量级Markdown文本编辑器
|
2月前
|
存储 安全 数据安全/隐私保护
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
107 0
|
1月前
|
JavaScript 前端开发 API
vue3 v-md-editor markdown编辑器(VMdEditor)和预览组件(VMdPreview )的使用
本文介绍了如何在Vue 3项目中使用v-md-editor组件库来创建markdown编辑器和预览组件。文章提供了安装步骤、如何在main.js中进行全局配置、以及如何在页面中使用VMdEditor和VMdPreview组件的示例代码。此外,还提供了一个完整示例的链接,包括编辑器和预览组件的使用效果和代码。
vue3 v-md-editor markdown编辑器(VMdEditor)和预览组件(VMdPreview )的使用
|
4月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
111 4
|
5月前
|
前端开发 C++ iOS开发
几款主流好用的markdown编辑器介绍
几款主流好用的markdown编辑器介绍
335 1
|
2月前
|
前端开发 Python
60行Python代码开发在线markdown编辑器
60行Python代码开发在线markdown编辑器
|
5月前
|
存储 移动开发 编解码
基于HTML5开发的Markdown在线编辑器
Markdown是一种轻量级标记语言,以其简洁易读的格式而备受程序员和作者们的青睐。随着互联网的发展,越来越多的在线Markdown编辑器应运而生,为用户提供了更加便捷、高效的写作和编辑环境。本文将探讨基于HTML5开发的Markdown在线编辑器的设计原理、功能特点以及技术优势。
71 1
基于HTML5开发的Markdown在线编辑器
|
4月前
|
Linux C++ 开发者
几款主流好用的markdown编辑器介绍
几款主流好用的markdown编辑器介绍
281 0
|
5月前
|
Web App开发 移动开发 搜索推荐
常见的Markdown在线编辑器
在线Markdown编辑器提供了更加稳定和流畅的用户体验。用户无需下载安装任何软件,只需打开浏览器,即可在任何设备上轻松使用这款编辑器,实现随时随地的写作。基于HTML5的在线Markdown编辑器可实现即时的编辑和预览功能
88 2
|
4月前
Markdown编辑器--冷门实用知识总结
Markdown编辑器--冷门实用知识总结