web 实现 markdown 编辑 + 实时预览

思路

使用 showdown 库完成 markdown 到html 的转换,再同步将 html 输出到 预览容器中,最后使用 js 完成左右两边 容器 滚动的同步

js库 showdown

css

我这里使用的是 github 风格的主题,下载请移步 https://github.com/sindresorhus/github-markdown-css

html 内容

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>markdown 编辑 + 预览</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"></script>
    <link href="./plug/github-markdown.css" rel="stylesheet"/>
    <style>
        .title{font-size: 20px;height: 30px; text-align: center;color: #009689; font-weight: bold;}
        .mk-editor{
            margin: 0;padding: 6px;border: 0;height: 630px;display: flex;justify-content: space-between;
            box-shadow: 0 0 5px #ccc;
        }
        .mk-editor > *{
            display: block!important;
            width: calc(50% - 5px)!important;
            height: 600px!important;word-wrap: break-word;
            overflow-y: scroll;padding: 10px;
        }
        #editor-edit {font-size: 15px;font-weight: 300;outline: none;}
        </style>
</head>

<body>
    <div class="title">Markdown转换为HTML的Demo</div>
    <div class="mk-editor">
        <textarea id="editor-edit" class="cur" name=""></textarea>
        <div id="editor-show" class="markdown-body"></div>
    </div>

    <script>
        let converter = new showdown.Converter(),
            container_edit = document.getElementById("editor-edit"),
            container_show = document.getElementById("editor-show");

        // 将输入框中的 markdown 语句 转换为html 输出到 预览容器中
        let translation = (function () {
            return function () {
                container_show.innerHTML = converter.makeHtml(container_edit.value);
                // 按比例调整 预览容器 的滚动条位置
                let ratio = container_edit.scrollTop/container_edit.scrollHeight;
                container_show.scrollTop = container_show.scrollHeight*ratio;
            }
        })();

        // 监听输入框输入,实时将输入内容同步的右侧 预览框
        container_edit.onkeyup = translation;

        //监听鼠标进入 输入框范围 设置状态 
        container_edit.onmouseover = function(){
            container_show.classList.remove('cur');
            container_edit.classList.add('cur');
        };
        //监听鼠标离开 输入框范围 设置状态 
        container_edit.onmouseleave = function(){
            container_edit.classList.remove('cur')
        };
        //监听鼠标进入 预览容器范围 设置状态 
        container_show.onmouseover = function(){
            container_edit.classList.remove('cur')
            container_show.classList.add('cur');
        };
        //监听鼠标离开 预览容器范围 设置状态 
        container_show.onmouseleave = function(){
            container_show.classList.remove('cur')
        };

        // 监听 输入框 内容滚动
        container_edit.addEventListener('scroll',function(){
            // 若鼠标在 输入框范围内 则 以输入框为主 同步 预览容器内容滚动条高度
            if(hasClass(container_edit, "cur")){
                let ratio = container_edit.scrollTop/container_edit.scrollHeight;
                container_show.scrollTop = container_show.scrollHeight*ratio;
            }
        });
        // 监听 预览容器 内容滚动
        container_show.addEventListener('scroll',function(){
            // 若鼠标在 预览范围内 则 以 预览容器为主 同步 输入框内容滚动条高度
            if(hasClass(container_show, "cur")){
                let ratio = container_show.scrollTop/container_show.scrollHeight;
                container_edit.scrollTop = container_edit.scrollHeight*ratio;
            }
        });

        // 判断 dom对象是否含有 指定 class 属性
        var hasClass = (function(){
            var div = document.createElement("div") ;
            if( "classList" in div && typeof div.classList.contains === "function" ) {
                return function(elem, className){
                    return elem.classList.contains(className) ;
                } ;
            } else {
                return function(elem, className){
                    var classes = elem.className.split(/\s+/) ;
                    for(var i= 0 ; i < classes.length ; i ++) {
                        if( classes[i] === className )return true ;
                    }
                    return false ;
                } ;
            }
        })() ;
    </script>
</body>
</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值