当前位置: 首页 > article >正文

使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅

最近,我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全,但生成的 HTML 代码繁杂,维护起来非常麻烦。为了追求更简洁高效的写作体验,我开始研究 Markdown 编辑器,并最终选择了 marked.min.js


1. 传统富文本 vs. Markdown 编辑器

在对比了传统富文本编辑器和 Markdown 编辑器后,我发现它们各有优缺点:

特性传统富文本编辑器Markdown 编辑器
易用性简单直观需学习语法
格式控制强大简洁清晰
代码质量冗余复杂干净整洁
维护性代码较难维护代码结构清晰
学习成本

由于 Markdown 语法简洁,生成的 HTML 代码清爽易读,我最终选择了 Markdown 作为博客的主要编辑格式,并决定使用 marked.min.js 来解析 Markdown。


2. marked.min.js 介绍

marked.min.js 是一个轻量级、高性能的 JavaScript 库,可以将 Markdown 文本快速转换为 HTML,适用于博客、文档系统等场景。

marked.min.js 的特点:

解析速度快:比普通正则解析方式更高效
支持 GitHub 风格 Markdown,兼容 CommonMark 规范
支持扩展,可以自定义渲染方式,如代码高亮等
简单易用,可直接解析 Markdown 并输出 HTML


3. 在博客后台集成 marked.min.js

步骤 1:引入 marked.min.js

可以通过 CDN 方式引入 marked.min.js,无需安装:

<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>

步骤 2:创建 Markdown 编辑区域

在 HTML 页面中,使用 textarea 输入 Markdown,并在 div 中实时显示解析后的 HTML:

<textarea id="markdown-input" placeholder="输入 Markdown..."></textarea> 
<div id="html-output"></div>

步骤 3:解析 Markdown 并实时更新 HTML

使用 marked() 函数,将 textarea 输入的 Markdown 解析为 HTML,并动态更新 div 内容:

const markdownInput = document.getElementById('markdown-input');
const htmlOutput = document.getElementById('html-output');markdownInput.addEventListener('input', () => {const markdownText = markdownInput.value;htmlOutput.innerHTML = marked.parse(markdownText);
});// 设置默认 Markdown 示例
markdownInput.value = "# Hello Markdown!\n\n- **加粗**\n- *斜体*\n- `代码块`\n\n[点击这里](https://github.com/markedjs/marked)";
htmlOutput.innerHTML = marked.parse(markdownInput.value);

步骤 4:优化和扩展功能

为了让 Markdown 编辑器更安全、更美观,我们可以进行以下优化:

防止 XSS 攻击(HTML 清理)

由于 marked 直接解析 Markdown 可能会导致 XSS 攻击,我们可以使用 DOMPurify 清理 HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.0/purify.min.js"></script>
htmlOutput.innerHTML = DOMPurify.sanitize(marked.parse(markdownText));


支持代码高亮

为了让代码块更美观,我们可以使用 highlight.js 进行语法高亮:

<script src="https://cdn.jsdelivr.net/npm/highlight.js/lib/common/highlight.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js/styles/github.min.css">
marked.setOptions({ highlight: function (code) { return hljs.highlightAuto(code).value; } });


自定义 Markdown 渲染方式

如果想自定义 Markdown 渲染方式(例如修改标题格式),可以使用 marked.use()

marked.use({ renderer: { heading(text, level) { return `<h${level} style="color:blue;">${text}</h${level}>`; } } });


4. 完整示例代码

 
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Markdown 编辑器</title><script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.0/purify.min.js"></script><script src="https://cdn.jsdelivr.net/npm/highlight.js/lib/common/highlight.min.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js/styles/github.min.css"><style>body { font-family: Arial, sans-serif; margin: 20px; }textarea { width: 100%; height: 150px; padding: 10px; font-size: 16px; }#html-output { border: 1px solid #ccc; padding: 10px; margin-top: 10px; min-height: 100px; background: #f9f9f9; }</style>
</head>
<body><h2>Markdown 编辑器</h2><textarea id="markdown-input" placeholder="输入 Markdown..."></textarea><div id="html-output"></div><script>marked.setOptions({highlight: function (code) {return hljs.highlightAuto(code).value;}});const markdownInput = document.getElementById('markdown-input');const htmlOutput = document.getElementById('html-output');markdownInput.addEventListener('input', () => {const markdownText = markdownInput.value;htmlOutput.innerHTML = DOMPurify.sanitize(marked.parse(markdownText));});markdownInput.value = "# Hello Markdown!\n\n- **加粗**\n- *斜体*\n- `代码块`\n\n[点击这里](https://github.com/markedjs/marked)";htmlOutput.innerHTML = DOMPurify.sanitize(marked.parse(markdownInput.value));</script>
</body>
</html>

5. 总结

通过 marked.min.js,我们可以轻松地在博客后台实现 Markdown 编辑器,实现 Markdown 解析、HTML 预览,并结合 highlight.js 添加代码高亮,同时使用 DOMPurify 保障安全性。

🔹 为什么选择 marked.min.js
✅ 解析速度快
✅ 代码清晰简洁
✅ 支持 GitHub 风格 Markdown
✅ 结合 highlight.js 让代码块更美观
✅ 可扩展性强,自定义渲染方式

这样,我们就完成了一个轻量级的 Markdown 编辑器,非常适合用于博客后台或在线 Markdown 解析工具!🚀

官方文档: Marked Documentation

相关文章:

使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅

最近&#xff0c;我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全&#xff0c;但生成的 HTML 代码繁杂&#xff0c;维护起来非常麻烦。为了追求更简洁高效的写作体验&#xff0c;我开始研究 Markdown 编辑器&#xff0c;并最终选择了 marked.min.js。 1. 传…...

Linux系统基于ARM平台的LVGL移植

软硬件介绍&#xff1a;Ubuntu 20.04 ARM 和&#xff08;Cortex-A53架构&#xff09;开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的&#xff0c;如果想要实现在ARM开发板上运行LVGL图形库&#xff0c;那么就需要把LVGL图形库提供的关于帧缓冲设…...

LeetCode 2070.每一个查询的最大美丽值:排序 + 二分查找

【LetMeFly】2070.每一个查询的最大美丽值&#xff1a;排序 二分查找 力扣题目链接&#xff1a;https://leetcode.cn/problems/most-beautiful-item-for-each-query/ 给你一个二维整数数组 items &#xff0c;其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和…...

电力场景绝缘子缺陷分割数据集labelme格式1585张4类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1585 标注数量(json文件个数)&#xff1a;1585 标注类别数&#xff1a;4 标注类别名称:["broken part","broken insulat…...

【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式

网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议&#xff1a; HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站&#xff0c;就是通过HTTP协议来…...

IPFS:下一代互联网传输协议

IPFS&#xff1a;下一代互联网传输协议 1. 引言2. IPFS概述3. IPFS的核心优势3.1 去中心化3.2 高效性3.3 安全性3.4 持久性3.5 可扩展性 4. IPFS的工作原理4.1 内容寻址4.2 分布式哈希表&#xff08;DHT&#xff09;4.3 文件分块4.4 版本控制4.5 网络协议 5. IPFS的应用场景5.1…...

线上接口tp99突然升高如何排查?

当线上接口的 TP99 突然升高时&#xff0c;意味着该接口在 99% 的情况下响应时间变长&#xff0c;这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99&#xff1a;监控系统计算 TP99&#xff08;第 99 百分位数的响应时间&…...

SpringBoot优雅关机,监听关机事件,docker配置

Spring Boot 提供了多种方法来实现优雅停机&#xff08;Graceful Shutdown&#xff09;&#xff0c;这意味着在关闭应用程序之前&#xff0c;它会等待当前正在处理的请求完成&#xff0c;并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下&#xff1a; …...

在【k8s】中部署Jenkins的实践指南

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…...

Unity DOTS从入门到精通之 C# Job System

文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程&#xff0c;我们将创建一个旋转立方体的简单程序&#xff0c;并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…...

Spring Boot 本地缓存工具类设计与实现

在 Spring Boot 应用中&#xff0c;缓存是提升性能的重要手段之一。为了更方便地使用缓存&#xff0c;我们可以设计一套通用的本地缓存工具类&#xff0c;封装常见的缓存操作&#xff0c;简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类&#xff0…...

【Godot4.4】浅尝Godot中的MVC

概述 基于一个Unity的视频。学习了一下基本的MVC概念&#xff0c;并尝试在Godot中实现了一下。 原始的MVC&#xff1a; Godot中的MVC&#xff1a; Model、View和Controller各自应该实现的功能如下&#xff1a; Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…...

如何解决前端的竞态问题

前端的竞态问题通常是指多个异步操作的响应顺序与发起顺序不一致&#xff0c;导致程序出现不可预测的结果。这种问题在分页、搜索、选项卡切换等场景中尤为常见。以下是几种常见的解决方法&#xff1a; 1. 取消过期请求 当用户发起新的请求时&#xff0c;取消之前的请求&…...

Elasticsearch为索引设置自动时间戳,ES自动时间戳

文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时&#xff0c;时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…...

计算机网络:计算机网络的组成和功能

计算机网络的组成&#xff1a; 计算机网络的工作方式&#xff1a; 计算机网络的逻辑功能; 总结&#xff1a; 计算机网络的功能&#xff1a; 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点&#xff08;计算机或设备&…...

FPGA设计时序约束用法大全保姆级说明

目录 一、序言 二、时序约束概览 2.1 约束五大类 2.2 约束功能简述 2.3 跨时钟域约束 三、时序约束规范 3.1 时序约束顺序 3.2 约束的优先级 四、约束示例 4.1 设计代码 4.2 时序结果 4.2.1 create_clock 4.2.2 create_generated_clock 4.2.3 Rename_Auto-Derive…...

云服务运维智能时代:阿里云操作系统控制台

阿里云操作系统控制台 引言需求介绍操作系统使用实例获得的帮助与提升建议 引言 阿里云操作系统控制台是一款创新型云服务器运维工具&#xff0c;专为简化用户的运维工作而设计。它采用智能化和可视化的方式&#xff0c;让运维变得更加高效、直观。借助AI技术&#xff0c;控制…...

硬件学习笔记--48 磁保持继电器相关基础知识介绍

目录 1.磁保持继电器工作原理 2.磁保持继电器内部结构及组成部分 3.磁保持继电器主要参数 4.总结 1.磁保持继电器工作原理 磁保持继电器利用永磁体的磁场和线圈通电产生的磁场相互作用&#xff0c;实现触点的切换。其特点在于线圈断电后&#xff0c;触点状态仍能保持&#…...

【云岚到家】-实战问题(上)

【云岚到家】-实战问题&#xff08;上&#xff09; 基础架构项目涉及那些角色云岚的业务流程&#xff1f;云岚家政包括那些模块项目采用什么架构如何开发一个接口&#xff1f;RESTful风格的去定义一个接口如何开发一个接口的service方法接口的异常处理怎么实现的&#xff1f;Sp…...

简记_硬件系统设计之需求分析要点

目录 一、 功能需求 二、 整体性能需求 三、 用户接口需求 四、 功耗需求 五、 成本需求 六、 IP和NEMA防护等级需求 七、 认证需求 功能需求 供电方式及防护 供电方式&#xff1a;市电供电、外置直流稳压电源供电、电池供电、PoE&#xff08;Power Over Ether…...

K8s 1.27.1 实战系列(五)Namespace

Kubernetes 1.27.1 中的 ​Namespace​(命名空间)是集群中实现多租户资源隔离的核心机制。以下从功能、操作、配置及实践角度进行详细解析: 一、核心功能与特性 ​1、资源隔离 Namespace 将集群资源划分为逻辑组,实现 Pod、Service、Deployment 等资源的虚拟隔离。例如,…...

ubuntu 20.04下ZEDmini安装使用

提前安装好显卡驱动和cuda&#xff0c;如果没有安装可以参考我的这两篇文章进行安装&#xff1a; ubuntu20.04配置YOLOV5&#xff08;非虚拟机&#xff09;_ubuntu20.04安装yolov5-CSDN博客 ubuntu20.04安装显卡驱动及问题总结_乌班图里怎么备份显卡驱动-CSDN博客 还需要提前…...

Deepseek可以通过多种方式帮助CAD加速工作

自动化操作&#xff1a;通过Deepseek的AI能力&#xff0c;可以编写脚本来自动化重复性任务。例如&#xff0c;使用Python脚本调用Deepseek API&#xff0c;在CAD中实现自动化操作。 插件开发&#xff1a;结合Deepseek进行二次开发&#xff0c;可以创建自定义的CAD插件。例如&a…...

tauri-plugin-shell插件将_blank的a标签用浏览器打开了,,,解决办法

不要使用这个插件&#xff0c;这个插件默认会将网页中a标签为_blank的使用默认浏览器打开&#xff0c;但是这种做法在我的程序里不是很友好&#xff0c;我需要自定义这种行为&#xff0c;当我点击我自己的链接的时候&#xff0c;使用默认浏览器打开&#xff0c;当点击别的链接的…...

[20250304] 关于 RISC-V芯片 的介绍

[20250304] 关于 RISC-V芯片 的介绍 1. 调研报告 一、RISC-V 芯片结构分析 RISC-V 芯片基于开源指令集架构&#xff08;ISA&#xff09;&#xff0c;其核心优势在于模块化设计与高度灵活性。 指令集架构 基础指令集&#xff1a;包含 RV32I&#xff08;32 位&#xff09;、R…...

C++ 继承(2)

Hello&#xff01;&#xff01;大家早上中午晚上好&#xff01;&#xff01;今天收尾继承剩余部分内容&#xff01;&#xff01; 一、友元不能继承 基类的友元函数不能被子类继承&#xff0c;也就是基类的友元函数访问不了子类的私有或保护成员&#xff01; 1.1解决方法在子…...

解决:Word 保存文档失败,重启电脑后,Word 在试图打开文件时遇到错误

杀千刀的微软&#xff0c;设计的 Word 是个几把&#xff0c;用 LaTex 写完公式&#xff0c;然后保存&#xff0c;卡的飞起 我看文档卡了很久&#xff0c;就关闭文档&#xff0c;然后 TMD 脑抽了重启电脑 重启之后&#xff0c;文档打不开了&#xff0c;显示 杀千刀的&#xff…...

【docker简化部署有状态prometheus+grafana】

文章目录 第一步 下载依赖第二步 选择一个有权限的文件夹新建配置文件prometheus.ymldocker中运行命令存储数据启动prometheus 第三步 启动grafana 第一步 下载依赖 docker pull grafana/grafana:latest docker pull prom/prometheus:latest第二步 选择一个有权限的文件夹 例…...

Java- “equals“和“==“

"equals" 用于比较是否相等 equals() 是Object类下的一个方法&#xff0c;而非运算符。所以只有引用数据类型才可以使用 equals()方法&#xff0c;基本数据类型不能使用 equals()方法; object类下的equals()源码 public boolean equals(Object obj) {return (this…...

使用 potrace.js实现图像矢量化教程

在现代Web开发中&#xff0c;将位图转换为矢量图形的需求日益增加。矢量图形具有可缩放性、无损质量等优点&#xff0c;适用于多种应用场景&#xff0c;如图标设计、数据可视化和响应式网页设计。potrace.js 是一个基于浏览器的JavaScript库&#xff0c;它实现了著名的Potrace算…...