手撕bejson,vue实现

2019-04-04  本文已影响0人  任然_c117

bejson 在线格式化json代码,算是比较好用的一款,经常会有项目需要编写提交json格式的数据。所以在这里分析一下它的代码格式以及实现方式!

一点点拆,如果有错误的地方欢迎指正。

首先chormf12调试:

image.png
很明显的一个textarea标签。但是隐藏掉了,我们先把它展开。
image.png

展开后修改,发现并不会影响,代码部分的展示,即便删掉后,功能也是正常的。暂不明白作者用这个标签的意图,可能是混淆视听?
接着往下看,先从使用方面分析:
每当我们切换鼠标位置时,代码的着两处会发生改变,仔细观察就可以知道,这两处,第一处是用来输入字符,第二处则是展示光标。


image.png

光标实现非常简单,div元素的 border,利用visibility属性闪烁形成光标:


image.png

而第一处的输入字符就比较复杂点:

image.png

这个地方有个 textarea 标签,标签上有个div这个元素使用了overflow: hidden;我们把它脱掉就可以直观的看到,它实际上是在你点击的时候修改了div的位置,把textarea 标签挪到你输入的地方。所有你的输入其实是在这个textarea 中进行的。

image.png

好了,目前已经知道了输入的实现,我们在往后看生成部分。

image.png

从上面的图片实验得知,每输入一行代码,他会生成一个div标签,div 里标签包含了,行号、以及代码片段。

那它是怎么实现的呢?我们先猜测一下。
首先它有一个CodeMirror-codediv容器,用来填充代码片段。先把代码删干净,发现它默认会有一个子div,也就是默认1行。

image.png

每当我们按下回车时,则会自动插入一行div到容器中,所以这里我猜测它监听了onmousedown 事件进行插入。
前面提到我们写入用的是textarea,所以事件自然绑定在它上面,因此我们找到了这个添加行的代码

image.png

它在一个min.js文件中,虽然混淆了,但是并不能阻止我了解它,我先猜测它是这个编辑器的js主文件,看看能否不往下拆解获取这个编辑器的功能。因此我们先解析这个js文件。

image.png
Ide中精简后可以看到,这其实是一个自执行文件。因此在这个app里面应该就是主方法,所以我们先看看这里面究竟是啥。 image.png

根据内容,里面有editorformquerycode
然后在我们一个个分解

editor: 根据里面的内容,很明显它是一个方法类。
form: 应该是放IDEdom
query: 目前还不清楚具体作用。
code: 写入的代码就存放在这里。

现在非常确定它就是我们要找的功能,那我们怎么去使用它。
既然它的domform,那我们先从form上做文章。

image.png
很明显的有个name="main" ,然后我们在js文件中查找。
很遗憾并没有找到有用的信息,那么它是怎么获取到这个from的呢?接着往下看。
我们把js文件拷贝下来,自己跑一遍。
image.png

发现了一个报错,根据报错往上看。

image.png
from 应该是从w.forms.main 中取得。
在它上面,我发现了
image.png
这样一来我们就知道了
form = document.forms.main

我们先给他加上from


image.png

再往下走,发现它还是会报错,还是上面的错误,缺少code
然后这里尴尬的发现我js引用的早了- -,要在dom 加载完引用js
现在我们的页面已经ok啦。
尝试使用一下

image.png

非常完美!接下来我把它搬到我的vue项目中去。

image.png

完成的效果图! 以上完毕。

最后附上扒好的html版源码

<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://cdn.staticfile.org/jquery/1.9.1/jquery.min.js"></script>
    <link rel="stylesheet" href="http://www.bejson.com/static/bejson/index/new/style.css?20180511">
</head>

<body>
    <div style="height: 400px;">
        <form name="main" onsubmit="return false" style="margin-top: 10px;">
            <textarea id="code" name="code" style="display: none;resize:both"></textarea>
            <div class="grippie" id="btnShouOrFang" onclick="" style="">点击俺最大化</div>
            <div class="validate">
                <div class="left1 validate" id="btn2019040416" style="float:left">
                    <div class="btn-group" role="group" aria-label="...">
                        <button class="copy hide" data-ga="copy"></button>
                        <input name="validate" data-ga="validate" type="submit" id="validate" class="btn btn-primary"
                            value="格式化校验">
                        <input type="button" onclick="show(1)" class="btn  btn-default" value="新版">
                        <input type="button" value="压缩" id="btnYasuo" class="btn btn-default" />
                        <input type="button" value="转义" id="btnZhuanyi" class="btn btn-default" />
                        <input type="button" value="去除转义" id="btnRemoveZhuanyi" class="btn btn-default" />
                        <input type="button" value="unicode转中文" id="btnToChar" class="btn btn-info" />
                        <input click-type="copy" onclick="$(this).attr('data-clipboard-text',app.editor.getValue())"
                            class="btn btn-default" type="button" value="复制" />
                        <input name="validate" class="btn btn-default"
                            onclick="javascript:json_input.value='';$('#json_input').focus(); " type="reset"
                            value="清空" />
                    </div>
                </div>
                <div>
                    <a href="http://www.dotcpp.com/oj/problemset.html?t=bejson_big" rel="external nofollow"
                        target="_blank"><span class="tg1" style="background: #118eab;">C语言在线编程训练题库</span></a>
                    <a href="//www.layui.com/admin/std/dist/views/?from=bejson" rel="external nofollow"
                        target="_blank"><span class="tg1" style="background: #009688;">layuiAdmin-通用后台管理模板</span></a>
                </div>
            </div>
        </form>
    </div>
</body>

</html>
<script src="http://upyun.bejson.com/js/bejson/bejson_index20190109.min.js" type="text/javascript"></script>
<style>
    * {
        font-family: "Microsoft YaHei", 微软雅黑, "MicrosoftJhengHei", 华文细黑, STHeiti, MingLiu;
    }
</style>

原创不易,转载请注明出处!

上一篇 下一篇

猜你喜欢

热点阅读