title: 通过浏览器加载的方式使用strapdown.js来渲染markdown
文章导读
- 如何手动调用
strapdown.js
的渲染方法 - html下如何将markdown 转换为html
- 如何拓展strapdown.js的功能
- 有哪些好用的markdown渲染库
本文关联的代码
作者修改后的strapdown.js代码库的github地址如下:
https://github.com/edocevol/strapdownify
项目中,附有三个demo,详情见文末
说明
strapdown是一个很棒的markdown解析库(当然是基于javascript)的了,但是作者的目的可能是尽可能的适用于所有的场景。
所以,作者在官网给出了如下的使用说明
<!DOCTYPE html>
<html>
<title>Hello Strapdown</title>
<xmp theme="united" style="display:none;">
# Markdown text goes in here
## Chapter 1
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.
## Chapter 2
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</xmp>
<script src="http://strapdownjs.com/v/0.2/strapdown.js"></script>
</html>
从上面的代码可以看出,我们需要在html中定义一个xmp
或者textarea
的html
元素(当然,如果你不看源码的话,是不会发现也可以用textarea
来替代xmp
元素的)。然后,根据源码中的描述,strapdown
会获取我们的xmp
中的markdown
代码,然后利用document
来解析我们页面中的link
、script
、meta
信息,然后将利用document.createElement
方法动态的对我们的当前页重新进行渲染。
为什么要修改作者的代码库
从上一节的描述中,我们可以了解到,原来的解析方式会替换我们的原始页面,也就是渲染过后的页面只会保留最基本的内容(渲染出来的markdown
)。因此,我们想有一种方式可以按需进行渲染。
因此,我们对原始的strapdown.js
进行了如下的修改(替换了原始文件的最后一个自执行函数):
/**
* 根据传入的$src来获取markdown的内容并转为html显示在$desc元素下
* 如果$desc元素为undefine,则显示$src元素中
* @param $src markdown内容的载体
* @param $desc 渲染过后markdown内容的载体
*/
var markdown = function ($src, $desc) {
if ($desc == undefined) {
$desc = $src;
}
document.body.style.display = 'none';
var markdownEl = document.getElementById($src);//markdown载体
var htmlEl = document.getElementById($desc); //html载体
var markdown = markdownEl.innerText;//注意这里必须是innerText,使用Jquery时,请使用$.text()
// Generate Markdown
var html = marked(markdown);
htmlEl.innerHTML = html;
// Prettify
var codeEls = document.getElementsByTagName('code');
for (var i = 0, ii = codeEls.length; i < ii; i++) {
var codeEl = codeEls[i];
var lang = codeEl.className;
codeEl.className = 'prettyprint lang-' + lang;
}
prettyPrint();
// Style tables
var tableEls = document.getElementsByTagName('table');
for (var i = 0, ii = tableEls.length; i < ii; i++) {
var tableEl = tableEls[i];
tableEl.className = 'table table-striped table-bordered';
}
// All done - show body
document.body.style.display = '';
};
/**
* 根据传入的$data作为markdown的内容并转为html显示在$desc元素下
* @param $data markdown内容
* @param $desc 渲染过后markdown内容的载体
*/
var markdownFromText = function ($data, $desc) {
// Generate Markdown
var html = marked($data);
document.getElementById($desc).innerHTML = html;
// Prettify
var codeEls = document.getElementsByTagName('code');
for (var i = 0, ii = codeEls.length; i < ii; i++) {
var codeEl = codeEls[i];
var lang = codeEl.className;
codeEl.className = 'prettyprint lang-' + lang;
}
prettyPrint();
// Style tables
var tableEls = document.getElementsByTagName('table');
for (var i = 0, ii = tableEls.length; i < ii; i++) {
var tableEl = tableEls[i];
tableEl.className = 'table table-striped table-bordered';
}
};
使用方式
由于我们对作者的原始库进行了大量的代码精简,因此,样式的选择,我们需要手动的加载themes
文件夹下的样式主题。
下面给出两个实际的使用案例
案例1
调用markdown
传递1个参数,可以原始的markdown载体元素作为渲染后的html的载体
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>strapdown渲染markdown的demo</title>
<link href="./static/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="./static/css/reset.css" rel="stylesheet">
<link href="./static/css/site.css" rel="stylesheet">
<link href="./static/css/lib.css" rel="stylesheet">
<link href="../strapdown/strapdown.css" rel="stylesheet">
<link href="../strapdown/themes/readable.min.css" rel="stylesheet">
</head>
<body>
<div class="bt-warp bge6">
<div id="container" class="container-fluid">
<div class="sidebar-scroll">
<div class="sidebar-auto">
<div id="task" class="task cw" onclick="task()"></div>
<h3 class="mypcip"><span class="f14 cw" id="serverip">localhost</span></h3>
<ul class="menu">
<li><a class="menu_home" href="index.html">demo1</a></li>
<li><a class="menu_folder" href="index2.html">demo2</a></li>
<li><a class="menu_fork" href="http://github.com/sixtrees/strapdownify">fork</a></li>
</ul>
</div>
</div>
<div class="main-content">
<div class="container-fluid" style="padding-bottom:50px">
<div id="mdcontent">
</div>
</div>
</div>
</div>
<div class="footer bgw">
markdown内容渲染框架 ©2017-2017
<a style="margin-left:20px;color:#20a53a;" href="http://github.com/sixtrees/strapdownify"
target="_blank">strapdownify on github</a>
</div>
</div>
<script src="./static/js/jquery-1.10.2.min.js"></script>
<script src="./static/js/bootstrap.min.js"></script>
<script src="./static/layer/layer.js"></script>
<script src="../strapdown/strapdown.js"></script>
<script>
var loadT = layer.msg('正在加载...', {icon: 16, time: 0, shade: [0.3, '#000']});
$.ajax({
url: 'readme.md',
type: "POST",
dataType: "text",
success: function (data) {
$("#mdcontent").text(data);
markdown("mdcontent");
layer.close(loadT);
}
});
</script>
</body>
</html>
案例2
调用markdown
传递两个参数,可以原始的markdown载体元素需要手动设置为隐藏
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>strapdown渲染markdown的demo</title>
<link href="./static/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="./static/css/reset.css" rel="stylesheet">
<link href="./static/css/site.css" rel="stylesheet">
<link href="./static/css/lib.css" rel="stylesheet">
<link href="../strapdown/strapdown.css" rel="stylesheet">
<link href="../strapdown/themes/readable.min.css" rel="stylesheet">
</head>
<body>
<div class="bt-warp bge6">
<div id="container" class="container-fluid">
<div class="sidebar-scroll">
<div class="sidebar-auto">
<div id="task" class="task cw" onclick="task()"></div>
<h3 class="mypcip"><span class="f14 cw" id="serverip">localhost</span></h3>
<ul class="menu">
<li><a class="menu_home" href="index.html">demo1</a></li>
<li><a class="menu_folder" href="index2.html">demo2</a></li>
<li><a class="menu_fork" href="http://github.com/sixtrees/strapdownify">fork</a></li>
</ul>
</div>
</div>
<div class="main-content">
<div class="container-fluid" style="padding-bottom:50px">
<textarea id="mdcontent" style="display: none;">
</textarea>
<div id="htmlcontent">
</div>
</div>
</div>
</div>
<div class="footer bgw">
markdown内容渲染框架 ©2017-2017
<a style="margin-left:20px;color:#20a53a;" href="http://github.com/sixtrees/strapdownify"
target="_blank">strapdownify on github</a>
</div>
</div>
<script src="./static/js/jquery-1.10.2.min.js"></script>
<script src="./static/js/bootstrap.min.js"></script>
<script src="./static/layer/layer.js"></script>
<script src="../strapdown/strapdown.js"></script>
<script>
var loadT = layer.msg('正在加载...', {icon: 16, time: 0, shade: [0.3, '#000']});
$.ajax({
url: 'readme.md',
type: "POST",
dataType: "text",
success: function (data) {
$("#mdcontent").text(data);
markdown("mdcontent", "htmlcontent");
layer.close(loadT);
}
});
</script>
</body>
</html>
案例3
调用markdownFromText
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>strapdown渲染markdown的demo</title>
<link href="./static/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="./static/css/reset.css" rel="stylesheet">
<link href="./static/css/site.css" rel="stylesheet">
<link href="./static/css/lib.css" rel="stylesheet">
<!--加载样式-->
<link href="../strapdown/strapdown.css" rel="stylesheet">
<link href="../strapdown/themes/readable.min.css" rel="stylesheet">
</head>
<body>
<div class="bt-warp bge6">
<div id="container" class="container-fluid">
<div class="sidebar-scroll">
<div class="sidebar-auto">
<div id="task" class="task cw" onclick="task()"></div>
<h3 class="mypcip"><span class="f14 cw" id="serverip">localhost</span></h3>
<ul class="menu">
<li><a class="menu_home" href="index.html">demo1</a></li>
<li><a class="menu_folder" href="index2.html">demo2</a></li>
<li><a class="menu_fork" href="http://github.com/sixtrees/strapdownify">fork</a></li>
</ul>
</div>
</div>
<div class="main-content">
<div class="container-fluid" style="padding-bottom:50px">
<div id="mdcontent">
</div>
</div>
</div>
</div>
<div class="footer bgw">
markdown内容渲染框架 ©2017-2017
<a style="margin-left:20px;color:#20a53a;" href="http://github.com/sixtrees/strapdownify"
target="_blank">strapdownify on github</a>
</div>
</div>
<script src="./static/js/jquery-1.10.2.min.js"></script>
<script src="./static/js/bootstrap.min.js"></script>
<script src="./static/layer/layer.js"></script>
<script src="../strapdown/strapdown.js"></script>
<script>
var loadT = layer.msg('正在加载...', {icon: 16, time: 0, shade: [0.3, '#000']});
$.ajax({
url: 'readme.md',
type: "POST",
dataType: "text",
success: function (data) {
markdownFromText(data, "mdcontent");
layer.close(loadT);
}
});
</script>
</body>
</html>
踩过的坑
不能直接用div的innerHtml或者jquery的html()方法来给markdown内容的载体设置值,应该使用text
或者innerText
。