likes
comments
collection
share

我给我的博客加了个在线运行代码功能

作者站长头像
站长
· 阅读数 31

获取更多信息,可以康康我的博客,所有文章会在博客上先发布随记 - 记录指间流逝的美好 (xiaoyustudent.github.io)

前言

新的一年还没过去,我又开始搞事情了,偶尔一次用到了在线编辑网页代码的网站,顿时想到,能不能自己实现一个呢?(PS:反正也没事干),然后又想着,能不能用在博客上呢,这样有些代码可以直接展现出来,多好,说干就干,让我们康康怎么去实现一个在线编辑代码的功能吧。(PS:有瑕疵,还在学习!勿喷!orz)

大致介绍

大概的想法就是通过iframe标签,让我们自己输入的内容能够在iframe中显示出来,知识点如下,如果有其他问题,欢迎在下方评论区进行补充!

  1. 获取输入的内容
  2. 插入到iframe中
  3. 怎么在博客中显示

当然也有未解决的问题:目前输入的js代码不能操作输入的html代码,查了许多文档,我会继续研究的,各位大佬如果有想法欢迎讨论

页面搭建

页面搭建很简单,就是三个textarea块,加4个按钮,就直接上代码了

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>在线编辑器</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script>
        $(document).ready(function () {
            $('.HTMLBtn').click(function () {
                $("#cssTextarea").fadeOut(function () {
                    $("#htmlTextarea").fadeIn();
                });
            })

            $('.CSSBtn').click(function () {
                $("#htmlTextarea").fadeOut(function () {
                    $("#cssTextarea").fadeIn();
                });
            })
        });
    </script>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body,
        html {
            width: 100%;
            height: 100%;
        }

        .main {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            width: 100%;
            height: 100%;
        }

        .textarea-box {
            display: flex;
            flex-direction: column;
            width: calc(50% - 20px);
            padding: 10px;
            background: rgba(34, 85, 85, 0.067);
        }

        .textarea-function-box {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
        }

        .textarea-function-left,.textarea-function-right {
            display: flex;
            flex-direction: row;
        }

        .textarea-function-left div,
        .textarea-function-right div {
            padding: 5px 10px;
            border: 1px solid rgb(9, 54, 99);
            border-radius: 3px;
            cursor: pointer;
        }

        .textarea-function-left div:not(:first-child) {
            margin-left: 10px;
        }

        #htmlTextarea,
        #cssTextarea {
            height: calc(100% - 30px);
            width: calc(100% - 20px);
            margin-top: 10px;
            padding: 10px;
            overflow-y: scroll;
            background: #fff;
        }

        .html-div {
            background-color: cadetblue;
            margin-top: 10px;
            flex: 1;
        }

        .iframe-box {
            width: 50%;
            flex: 1;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <div class="main">
        <div class="textarea-box">
            <div class="textarea-function-box">
                <div class="textarea-function-left">
                    <div class="HTMLBtn">HTML</div>
                    <div class="CSSBtn">CSS</div>
                </div>
                <div class="textarea-function-right">
                    <input type="text" id="input_name">
                    <div class="run">运行</div>
                    <div class="download">保存</div>
                </div>
            </div>
            <textarea id="htmlTextarea" placeholder="请输入html代码"></textarea>
            <textarea id="cssTextarea" placeholder="请输入css代码" style="display: none;"></textarea>
        </div>
        <div class="iframe-box">
            <iframe style="height: 100%;width: 100%;" src="" frameborder="0"></iframe>
        </div>
    </div>
</body>
</html>

忽略我的样式,能用就行!!

运行代码

这里是核心功能,应该怎么把代码运行出来呢,我这里用的是iframe,通过获取iframe元素,然后把对应的代码插入进去

$('.run').click(function () {
    var htmlTextarea = document.querySelector('#htmlTextarea').value;
    var cssTextarea = document.querySelector('#cssTextarea').value;
    htmlTextarea += '<style>' + cssTextarea + '</style>'
    // 获取html和css代码
    let frameWin, frameDoc, frameBody;
    frameWin = document.querySelector('iframe').contentWindow;
    frameDoc = frameWin.document;
    frameBody = frameDoc.body;
    // 获取iframe元素

    $(frameBody).html(htmlTextarea);
    // 使用jqury的html方法把代码插入进去,这样能够直接执行
})

这样一个基本的在线代码编辑网页就完成了,接下来,我们看下怎么把这玩意给用在博客当中!

hexo设置

首先我们需要创建一个文件夹,用来放置我们写好的在线的html文件。在source文件夹下新建文件online,并且设置禁止渲染此文件夹,打开_config.yml文件,并设置以下

skip_render: online/*

页面设置

我目前想到的办法就是保存文件,然后在hexo里使用,添加以下代码

<div class="textarea-function-right">
    <input type="text" id="input_name">
    <div class="download">保存</div>
    <!-- .... -->
</div>
<script>
    function fake_click(obj) {
        var ev = document.createEvent("MouseEvents");
        ev.initMouseEvent(
            "click", true, false, window, 0, 0, 0, 0, 0
            , false, false, false, false, 0, null
        );
        obj.dispatchEvent(ev);
    }

    function export_raw(name, data) {
        var urlObject = window.URL || window.webkitURL || window;
        var export_blob = new Blob([data]);
        var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
        save_link.href = urlObject.createObjectURL(export_blob);
        save_link.download = name;
        fake_click(save_link);
    }

    $(document).ready(function () {
        $(".download").click(function () {
            let scriptStr = $('html').first().context.getElementsByTagName("script")[2].innerHTML
            var htmlTextarea = document.querySelector('#htmlTextarea').value != "" ? document.querySelector('#htmlTextarea').value : '""';
            var cssTextarea = document.querySelector('#cssTextarea').value != "" ? document.querySelector('#cssTextarea').value : '""';
            let htmlStr = $('html').first().context.getElementsByTagName("html")[0].innerHTML.replace(scriptStr, "").replace('<div class="download">保存</div>', "").replace('<input type="text" id="input_name">',"").replace("<script><\/script>", "<script>$(document).ready(function(){document.querySelector('#htmlTextarea').value = `" + htmlTextarea + "`;document.querySelector('#cssTextarea').value = `" + cssTextarea + "`;})<\/script>")
            let n = $('#input_name').val()!=""?$('#input_name').val():"text";
            export_raw(n+'.html', htmlStr);
        })
    })
</script>

可能很多同学会好奇为啥我这里用的script标签框起来,我们看下这个图片和这个代码

我给我的博客加了个在线运行代码功能

et scriptStr = $('html').first().context.getElementsByTagName("script")[2].innerHTML

很简单,我们保存后的代码,是没有这一段js代码的,所以需要替换掉,而这里一共有3个script块,最后一个,也就是下标为2的script块会被替换掉。同理,后面替换掉保存按钮,input输入框(输入框是输入文件名称的,默认名称是text)。

同时这里把我们输入的数据,通过js代码的方式加入进保存后的文件里,实现打开文件就能看到我们写的代码。之后我们把保存后的文件放在刚才我们创建的online文件夹下

我给我的博客加了个在线运行代码功能

hexo里面使用

使用就很简单了,我们通过iframe里面的src属性即可

<iframe src="/online/text.html" style="display:block;height:400px;width:100%;border:0.5px solid rgba(128,128,128,0.4);border-radius:8px;box-sizing:border-box;"></iframe>

展示图

我给我的博客加了个在线运行代码功能

转载自:https://juejin.cn/post/7191520909709017144
评论
请登录