作为软件开发人员,软件做好后,接下来就是编写文档。我自己也是做软件的,经常有用户询问软件的安装与使用,

我一直很喜欢微软的MSDN帮助系统,简介、大气,使用方便。

网上也找了很久,感觉一直没有合适的,

所以,花了一周时间写了一个仿MSDN的系统 kbase(演示见  http://demo.dotnetcms.org/kbase)。

这篇文章来分析在制作这个系统遇到的几个问题以及总结。

如果分析微软MSDN,不难发现,他的左边是一个导航树,中间是正文,右边是正文的快速链接。

(1)树导航

在选择导航树时,我最初考虑的是bootstrap-treeview

不管从界面还是功能上,他和MSDN的帮助系统导航树都很像。

但是,如果我们仔细观察MSDN,他的导航树里,当点击父节点时是展开子节点,

只有点击“子节点”才能才会打开正文(参考下图)。

但是,这个功能bootstrap treeview控制的并不是很好。

bootstrap treeview点击父节点是打开文字,只有点击父节点前面的“+”才会展开子节点。

所以,最终选择了zTree,在zTree官方给的Demo里,有一个Outlook风格的模板,简直就是MSDN的原型。

同时,ztree提供的接口和功能远远比bootstrap-treeview强大,所以很快我就选中了她。

要使用zTree,首先定义zTree的配置seeting,然后在代码里,重新了onClick事件。

在onClick事件里,判断用户点击的节点有没有子节点,

如果有子节点,就展开子节点,

如果没有子节点,就打开网址。

var setting = {
view: {
showLine: false,
showIcon: false,
selectedMulti: false,
dblClickExpand: false,
addDiyDom: addDiyDom
},
data: {
simpleData: {
enable: true
}
}, callback: {
onClick: onClick
}
}; function onClick(e, treeId, treeNode) { if (treeNode.children != null) {
var zTree = $.fn.zTree.getZTreeObj("treeNav");
zTree.expandNode(treeNode);
}
else {
if (treeNode.id > 0) {
}
else {
window.location = "default.aspx?id=" + treeNode.id+"&title="+treeNode.name;
}
}
} function addDiyDom(treeId, treeNode) {
var spaceWidth = 5;
var switchObj = $("#" + treeNode.tId + "_switch"),
icoObj = $("#" + treeNode.tId + "_ico");
switchObj.remove();
icoObj.before(switchObj); if (treeNode.level >= 1) {
var spaceStr = "<span style='display: inline-block;width:" + (spaceWidth * treeNode.level) + "px'></span>";
switchObj.before(spaceStr);
}
}

(2)导航树的子节点是类别还是标题

但是,这样又遇到第二个问题:

左边导航树里的内容,到底是按照“分类”处理还是按照“新闻标题”处理。

开发过CMS(内容管理系统)的朋友都知道,一般CMS系统都是:

建立一个catetory分类,然后新闻会有一个标题title,和一个分类catID和分类表关联。

那MSDN左边导航树,用户点击的具体内容到底算“类别”还是“新闻标题”呢?

我最初的想法是算类别,左边设想的是一张表,里面存储所有的导航树“节点”,但是你能想象出来,

如果文章内容越来越多,构建导航树维护是比较困难。

最终,我决定,MSDN导航树,父节点都是“类别”,而叶节点才是新闻的标题,

系统实现里,建了两张表,这两张表通过 SQL的union all 关键字进行合并,然后作为数据源提供给zTree

select id, pId, catname as name,  orderid  from kb_cat
union all
select id, catid as pId, title as name, orderid from kb_news

(3)编辑器选择

在一开始,我就定位了后台编辑器必须使用Markdown(MD)编辑器,

原因很简单,这个仿MSDN的系统更偏向知识的传递,注重的是内容而不是界面,

而传统的HTML编写帮助文档,会产生大量的“垃圾代码”,这不是我想要的。

因此,接下来就是开始寻找MD编辑器。

我最先想到的是博客园后台有markdown编辑器,所以看看博客园怎么做的吧

但是很快放弃使用博客园的MD了,原因有2点:

(1)他的编写和预览是分开的,这不是我想要的,我希望左边是录入页面,右边是实时预览。

(2)View Source页面,天,博客园的源代码是全压缩的JS, 完全看不到他引用了哪些JS。

算了,放弃把

接下来就是痛苦的寻找过程。

包括  几款主流好用的markdown编辑器介绍 等,但是,都感觉差了那么点意思,不是我想要的。

最终,皇天不负有心人,无意中点到了“叶子岛”(叛道)网站,

然后看到了一个“ipandao(爱叛道)”的MD编辑器。

(题外话,这个编辑器名字太难记了,所以,软件开发还是要取一个容易记忆的名字。)

点进去看看 https://pandao.github.io/editor.md/ 界面美观,大方,左右布局,提供实时预览,提供自定义扩展,

而且内置和codemirror集成,支持代码高亮显示,而且还开源,源代码的JS里也没有使用太复杂的技术。

 这正是我想要的,这真的是太好了。

很快,我就把这个系统集成到仿MSDN的系统里。同时,自定义了工具栏,移除了没用的,只保留10来个按钮。

下面是代码的实现

        <script type="text/javascript">
var testEditor; $(function () {
testEditor = editormd("test-editormd", {
width: "100%",
height:520,
placeholder: "",
lineNumbers:true,
path: "../javascript/pandao-markdown/lib/",
toolbarIcons: function () {
return ["bold", "quote", "|", "h3", "h4", "h5", "h6", "list-ul", "list-ol", "|", "link", "image", "|", "code", "code-block", "table"]
}, imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "save_img.aspx",
saveHTMLToTextarea : true });
});
</script>

  

(4)新闻内容的存储

在上一步使用了ipandao的md后,他提供了2个方法用来获取录入的内容:

testEditor.getMarkdown();       // 获取 Markdown 源码
testEditor.getHTML(); // 获取 Textarea 保存的 HTML 源码

接下来一个问题,用户写好的MD以怎么的格式存储到MSSQL里?

如果直接存储HTML,那么后期用户将无法编辑文章,因为MD无法直接加载HTML,他识别不了HTML。

如果直接存储MD,那么浏览器并不能识别MD,这就要用户访问帮助文档时,每次都JS解析MD,可能用户感觉速度会没那么快。

如果同时存储HTML和MD,前端浏览器显示用HTML,后台,用户更新时用MD,通过程序保存数据同步,这会占用数据库空间。

总之,基本上没有完美的解决方法。

在我的做法里,是直接存储MD源代码,然后前端用户访问时,利用MD提供的markdownToHTML方法,转换为HTML进行渲染。

我看了MSDN,猜测他应该是MD和HTML同时存储。

 testEditor.markdownToHTML("contents");

(5)右边快速预览

右边快速预览其实是从MD里提取<h3>标题实现的。

$(function () {
editormd.markdownToHTML("contents");
let menu = "<h5>本页内容</h4>";
$("#contents h3").each(
function () {
menu += "<a class='quick_a' href='#" + $(this).text() + "'>" + $(this).text() + "</a>";
}
); $("#rightmenu").html(menu);
$("#rightmenu").pin({
minWidth: 800,
padding: { top: 50 }
}); });

  

在上面,还是用了一个插件:jquery.pin()。

他的作用但是:当页面过长,往下滚动时,他会把右边导航“钉”在右上角。

这样,一个仿MSDN核心功能介绍完了,剩下的就是普通的数据库增删读写了。

本系统演示见  http://demo.dotnetcms.org/kbase 用户名 admin,密码123456

仿MSDN的帮助系统的更多相关文章

  1. Windows XP SP3 Professional 微软(MSDN)官方原版系统

    Windows XP SP3 Professional 微软(MSDN)官方原版系统 Windows XP(版本号:5.1,开发代号:Whistler)是微软公司推出供个人电脑使用的操作系统,其RTM ...

  2. 仿5173游戏交易平台系统SQL注入(可直接脱裤)+Getshell

    最近没事登登好几年前玩过的游戏看看,发现有人喊高价收号,这一看就是骗子,这等骗子还想骗我?我就来看看这逗逼是怎么骗人的,结果发现这人给了一个说是 5173平台交易的网站,叫我直接把号的信息填上去然后填 ...

  3. 最全的微软msdn原版windows系统镜像和office下载地址集锦

    随着windows的发展,越来越多的人都热衷于微软的原版系统下载了,相比之前的版本比如winxp版本,windows vista/win7/win8/win8.1/win10后来的版本在安装方面也比较 ...

  4. win10全系列官方MSDN原版系统安装密钥、版本区别、镜像下载地址与激活教程

    微软发布win10正式版已经过去几天了,相信很多同学都心情高涨的装上了期待已久的win10系统,但也有很多同学面对win10系统的众多版本感到一脸茫然,的确,微软在win10系统版本上的划分确实有点多 ...

  5. 重装系统之制作U盘启动盘

    准备: 1.需要一个大于4G的U盘. 2.一个原版系统. 3.制作U盘启动盘的工具—ultraliso. 一.一个大于4G的U盘 制作启动盘将会格式化U盘,记得做好备份. 二.一个原版系统 至于你要装 ...

  6. Flask:Flask的模板系统和静态文件

    1.Flask模板系统 Django框架有自己独立的模板系统,而Flask是没有的,Flask默认采用jinjia2模板系统,jinjia2是仿写Django模板系统的一个第三方模块,但性能上要比Dj ...

  7. IO操作

    /// <summary> /// 文件读写操作/// </summary> public partial class TestIO : DevComponents.DotNe ...

  8. 【高清未加密】2015传智播客 最新21期c#asp.net 基础到就业班视频和源码

    [.NET]传智播客第[21]期就业班视频(高清无加密)本套2015年21期传智播客C#ASP.NET win10通用mvc+app开发视频教程附源码,是一套非常不错的asp.net自学视频教程,传智 ...

  9. C# 文件与目录的基本操作(System.IO)

    1. 文件操作 /// <summary> /// 文件读写操作 /// 为简化代码供大家学习,暂不考虑捕捉异常 /// </summary> public partial c ...

随机推荐

  1. L3-015. 球队“食物链”【DFS + 剪枝】

    L3-015. 球队"食物链" 时间限制 1000 ms 内存限制 262144 kB 代码长度限制 8000 B 判题程序 Standard 作者 李文新(北京大学) 某国的足球 ...

  2. C++ part6

    C++源文件从文本到可执行文件经历的过程 references: 一个C++源文件从文本到可执行文件经历的过程 C++源文件从文本到可执行文件经历的过程 gcc程序编译的静态链接和动态链接 保留中间过 ...

  3. Web 实时通信方案 All In One

    Web 实时通信方案 All In One HTTP 轮询, 单向通信,开销大 HTTP 长轮询, 单向通信,开销较小 WebSocket,双向通信,开销小 (TCP 高延迟,保证数据完整性) Ser ...

  4. select notes mark

    select notes mark mark-line https://time.geekbang.org/column/article/224545

  5. Clean Code of JavaScript

    Clean Code of JavaScript 代码简洁之道 JavaScript 版 https://github.com/ryanmcdermott/clean-code-javascript ...

  6. back to top & back to bottom

    back to top & back to bottom infinite auto load more & infinite scroll & load more https ...

  7. js 创建XML

    // 创建xml数据 let doc = document.implementation.createDocument('', 'root', null); // 创建一个文档 let root =d ...

  8. Android Kotlin 数据驱动模板

    Android开发人员文档: 数据绑定入门 数据绑定库 生成的绑定类 布局和绑定表达式 1. 搭建环境build.gradle:app apply plugin: "kotlin-kapt& ...

  9. 《Activity显示界面历险记》—说说View的那些理不清的关系

    前言 在Activity显示View的过程中,有一些重要的角色总让人理不清,比如PhoneWindow.DecorView.ViewRootImpl. 也常常有面试题会问到,他们四者之间的关系?创建的 ...

  10. winform解析json API数据

    {  "retCode" : "SUCCESS",  "msg" : "",  "data" : { ...