。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Markdown实时预览编辑器</title>
<!-- 引入 marked.js 库 -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- 引入自定义样式 -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<textarea placeholder="在这里输入您的Markdown内容..."></textarea>
<div class="content"></div>
</div>
<!-- 引入自定义脚本 -->
<script src="script.js"></script>
</body>
</html>在
中,我们通过CDN引入了marked.js库,以便在JavaScript中使用其解析功能。
2. CSS样式
为了让输入框和预览区域并排显示,并占据整个页面高度,我们可以使用Flexbox进行布局。
/* style.css */
html,
body {
margin: 0;
height: 100%; /* 确保body占据整个视口高度 */
font-family: sans-serif;
}
.container {
display: flex; /* 启用Flexbox布局 */
height: 100%; /* 容器占据整个body高度 */
border: 1px solid #ccc;
box-sizing: border-box; /* 边框包含在尺寸内 */
}
.container > * {
flex: 1; /* 子元素等宽占据容器空间 */
padding: 15px;
overflow: auto; /* 内容超出时显示滚动条 */
box-sizing: border-box;
}
textarea {
border: none; /* 移除textarea默认边框 */
resize: none; /* 禁止textarea手动调整大小 */
font-size: 16px;
line-height: 1.6;
background-color: #f9f9f9;
border-right: 1px solid #eee; /* 分隔线 */
}
textarea:focus {
outline: none; /* 移除焦点边框 */
}
.content {
background-color: #fff;
font-size: 16px;
line-height: 1.6;
/* 预览区域的Markdown样式,例如: */
h1, h2, h3, h4, h5, h6 { margin-top: 1em; margin-bottom: 0.5em; }
p { margin-bottom: 1em; }
strong, b { font-weight: bold; }
em, i { font-style: italic; }
blockquote {
margin: 0 0 1em 1em;
padding-left: 1em;
border-left: 4px solid #ccc;
color: #666;
}
pre {
background-color: #eee;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
code {
font-family: monospace;
background-color: #f0f0f0;
padding: 2px 4px;
border-radius: 3px;
}
}3. JavaScript逻辑
这是实现实时预览的核心部分。我们将获取textarea和content元素的引用,然后监听textarea的input事件。每当用户输入时,就调用marked.parse()方法将textarea中的Markdown文本转换为HTML,并将其设置到content元素的innerHTML中。
// script.js
const textarea = document.querySelector('textarea');
const content = document.querySelector('.content');
// 定义更新函数,用于解析Markdown并更新预览区域
const updatePreview = () => {
// marked.parse() 将 Markdown 字符串转换为 HTML 字符串
content.innerHTML = marked.parse(textarea.value);
};
// 监听 textarea 的 input 事件,每次输入都触发更新
textarea.addEventListener('input', updatePreview);
// 设置初始值,并立即更新一次预览
textarea.value = '**加粗文本** \n*斜体文本* \n\n> 这是一段引用。 \n\n- 列表项1 \n- 列表项2 \n\n`行内代码` \n\n```javascript\nconst hello = "world";\nconsole.log(hello);\n```';
updatePreview(); // 页面加载时执行一次更新,显示初始内容代码解析:
- document.querySelector('textarea') 和 document.querySelector('.content'):获取页面上的textarea和div.content元素。
- marked.parse(textarea.value):这是marked.js库提供的核心方法,它接收一个Markdown字符串作为参数,并返回相应的HTML字符串。
- content.innerHTML = ...:将解析后的HTML字符串插入到预览区域,浏览器会自动渲染这些HTML。
- textarea.addEventListener('input', updatePreview):input事件会在textarea内容每次发生变化时触发,确保了实时预览的效果。
- textarea.value = '...' 和 updatePreview():在页面加载时设置一些默认的Markdown内容,并立即渲染出来,方便用户理解功能。
运行效果
将上述HTML、CSS和JavaScript代码分别保存为index.html、style.css和script.js,并确保它们在同一目录下。用浏览器打开index.html文件,您将看到一个左侧为Markdown输入框、右侧为实时预览区域的页面。当您在左侧输入Markdown语法时,右侧会立即显示格式化后的内容。
注意事项与扩展
-
安全性: 当渲染用户生成的内容时,务必注意潜在的跨站脚本攻击(XSS)。marked.js在默认情况下会进行一些基本的HTML清理,但对于生产环境,建议结合更严格的DOM净化库(如DOMPurify)来确保安全性。
-
其他Markdown解析器: 除了marked.js,还有markdown-it等优秀的Markdown解析库,它们可能在性能、插件生态或特定功能上有所侧重。您可以根据项目需求选择最合适的库。
-
高级功能: 如果需要更复杂的富文本编辑功能,例如图片上传、表格、自定义字体等,可能需要考虑使用功能更全面的WYSIWYG编辑器(如TinyMCE、Quill.js等)。但对于仅需基本文本格式化的情况,Markdown方案无疑更轻量、更易于集成。
-
服务器端渲染: 在某些场景下,您可能希望在服务器端对Markdown进行解析,例如为了SEO优化、生成静态页面或确保内容在不同客户端上的一致性。许多后端语言都有相应的Markdown解析库。
总结
通过本教程,我们学习了如何利用Markdown和JavaScript前端解析器(如marked.js)来构建一个支持文本格式化和实时预览的自定义输入框。这种方法不仅实现了加粗、斜体、引用等常见格式化功能,还保持了代码的简洁性和高效性,为用户提供了直观且强大的内容编辑体验。在开发需要用户生成内容的Web应用时,Markdown无疑是一个值得考虑的优秀选择。