KindEditor优化、修复BUG与漏洞以及整合SyntaxHighLighter方案汇总

一 取消上传网络图片选项

找到 KindEditor/plugins/image/image.js     第13

?
1
allowImageRemote = K.undef(self.allowImageRemote, true)

true 改为 false 即可,前后对比图效果如下:

before:

after:

二 解决无法保存空格的BUG

找到 KindEditor/kindeditor.js

大约第752行 将第一个和最后一个 \s 替换成 [ \f\n\r\t\v]  完整代码如下:

?
1
var re =  /([ \f\n\r\t\v]*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>([ \f\n\r\t\v]*)/g;
三 解决复制粘贴、点击图片等操作滚动条自动下拉的BUG

找到 KindEditor/kindeditor.js

大约第1521行 将 y = box.top + pos.y; 替换成

?
1
y = pos.y;
四 图片上传路径问题

举个栗子:修改图片上传路径为根目录下的atcImg文件夹:

找到 KindEditor/php/upload_json

$save_path为图片上传的路径    $save_url为KindEditor中生成img标签的url路径   修改成下图所示即可:


KindEditor默认上传图片生成的url路径是不带域名的绝对路径,如果我们希望生成之后带上域名就需要对urlType进行设置了.

KindEditor中的urlType有4个参数,默认空值" "、"relative"、"absolute""domain"初始化kindeditor时可以指定以下参数:

urlType  : " "                 //默认为空,绝对路径

urlType  : "relative"           //相对路径

urlType  : "absolute"           //绝对路径

urlType  : "domain"           //带域名的绝对路径。

3种不同的路径效果如下图所示:

绝对路径 :

相对路径 :

带域名的绝对路径 :

五 解决文本中插入的程序代码里的HTML实体标签被直接解析出来的BUG

在PHP中添加此函数 , 在向Kindeditor中插入文本内容之前使用此函数将文本内容中的实体符号替换即可解决

?
1
2
3
4
5
6
function htmlRep($html){
    $html = str_replace(' ', ' ', $html);
    $html = str_replace('>', '>', $html);
    $html = str_replace('<', '<', $html);
    return $html;
}
六 美化样式

设置KindEditor生成的iframe中的样式(也就是编辑器内容框的样式)

例如 : 修改body的内边距为10px

进入kindeditor.js  第3535行  找到_getInitHtml函数 第一行arr数组里的代码就是iframe的HTML内容

那么直接将style标签中的 'body {margin:0;padding:5px;}' 替换为 'body {margin:0;padding:10px;}' 即可

整合SyntaxHighlighter至编辑器中

一般大家都是在文章页引入语法高亮插件 , 在这里我想说的是 , 为什么不直接引入至编辑器中呢? 不要嫌麻烦, 带来好处是不言而喻的:

是可以直接在编辑器就中看到代码被的效果 , 一点都没有的代码在写文章的时候是真滴辣眼睛

是减少文章页的HTTP请求 , 减少服务器压力 , 提升页面加载速度 , 仅仅引入一个css文件即可

SyntaxHighlighter异步的 , 访客访问你的文章页假如内容特别多, 那么在DOM没有加载完 , 你的代码就等着不会被着色 , 很难受!

那么废话就不多讲了, 直接上干货

1 首先需要引入SyntaxHighlighter.css 在初始化Kindeditor时指定cssPath

?
1
cssPath : './SyntaxHighlighter/styles/shCoreDefault.css'
2 进入kindeditor.js  第3594行 将arr.push中的内容替换为如下(在编辑器生成的iframe中引入SyntaxHighlighter的JS文件):
?
1
arr.push('</head><body ' + (bodyClass ? 'class="' + bodyClass + '"' : '') + '><script src="./SyntaxHighlighter/scripts/0.js"></script><script src="./SyntaxHighlighter/scripts/shCore.js"></script><script src="./SyntaxHighlighter/scripts/shBrushJScript.js"></script></body></html>');

注意 : 0.js这个文件是个空文件 , 原因是KindEditor有一个蜜汁BUG, 不解析引入的第一个JS文件 , 可能是哪里设置了什么东西吧 , 那我们不理它就好了直接在这里引入SyntaxHighlighter的JS文件之前先引入一个空文件来解决这个BUG

3 进入KindEditor/plugins/code.js 将默认的pre标签的class改成SyntaxHighlighter需要的class

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
yesBtn : {
    name : self.lang('yes'),
    click : function(e) {
        var type = K('.ke-code-type', dialog.div).val(),
            code = textarea.val(),
            //更改了这里 将class替换成"brush: js"这种形式 ("brush: "是固定的 , "js"是上面options中的val值)
            cls = type === '' ? '' : type,
            html = '<pre class="brush: ' + cls + '">\n' + K.escape(code) + '</pre>';
        if (K.trim(code) === '') {
            alert(lang.pleaseInput);
            textarea[0].focus();
            return;
        }
        self.insertHtml(html).hideDialog().focus();
        //加入了此行 每次插入代码后调用highlight()方法着色pre标签的代码
        document.getElementsByClassName('ke-edit-iframe')[0].contentWindow.SyntaxHighlighter.highlight();
    }
}

//找到43yesBtn属性, 将其替换为以上代码, 然后你需要清除以前的缓存, 下次在插入代码后就能让代码立刻被着色

那么骚年, 你以上已经完事了吗?不存在的, 是不是感觉还差点什么?快想想~

猜到了吗? 你还需要增加一个隐藏域来保存编辑器的内容, 为啥?因为Kindeditor还有个很烦的BUG: 源码中的div标签里的值被强行缩进

可以来看看是什么样子的, 你改完就能发现这个东西了, 点击显示HTML代码的那个按钮, 原本着色后的代码行号是这样的:

很整齐对吧~

然而kindEditor显示的源码中竟然被莫名其妙弄出这么大片空白出来, 你想改还改不掉:

虽然在编辑器中样式是正确的, 但是插入到数据库中空白就会被保存下来, 再放到文章页显示那效果就爆炸咯, 是这个样子 :


没办法, 这个时候只能增加一个隐藏域来接受iframe中的HTML值, 提交之前将值保存进去, 再插入到数据库

那么保存下来的代码就不会有一点缩进, 做法也很简单, 上代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//HTML Tag
<input type="hidden" class="hidden" name="content" required>
 
//Helper
function C(c, a, f){
    if(a){
        return f ? f.getElementsByClassName(c) : document.getElementsByClassName(c);
    }else{
        return f ? f.getElementsByClassName(c)[0] : document.getElementsByClassName(c)[0];
    }
}
 
function rmCd(p, c){
    var i = 0;
    while(c[i]){
        p.removeChild(c[i]);
    }
}
 
//Submit Event
C('form').onsubmit = function(e){
    var b = C('ke-edit-iframe').contentWindow.document.body,
        s = b.getElementsByTagName('script'),
        k = C('ke-script', false, b),
        h = C('hidden');
    rmCd(b, s);
    if(k){ rmCd(b, k); }
    h.value = b.innerHTML;
};

//你需要一个如上所示的input隐藏域, 和一个class为form的form表单, 将这段代码加入到你的提交页面中,

//在提交之前会通过submit事件将body中的HTML代码加入到隐藏域中, 然后通过后台提交到数据库

//C函数是我常用的获取element的自定义函数 rmCd函数功能是将多余的div和JS标签删除, 只取出纯真~的文章内容的HTML代码

完成以上工作后, 基本算是大工告成了, 但是还可能出现小瑕疵 , 经过测试Chrome下可能出现行数稍有误差的情况 , Firefox下却不会

那么解决这种问题也很简单, 单独给Chrome加个样式就好了 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//kindeditor.js 大约3586行 找到此函数_each() 将其内容替换为以下内容即可
_each(cssPath, function(i, path) {
    if (path) {
        arr.push('<link href="' + path + '" rel="stylesheet">');
        arr = arr.concat([
            '<style>',
            '@media screen and (-webkit-min-device-pixel-ratio:0) {',
            '    .syntaxhighlighter table td {',
            '        font-family:"Microsoft YaHei" !important;',
            '    }',
            '    .syntaxhighlighter a, .syntaxhighlighter div, .syntaxhighlighter code, .syntaxhighlighter table, .syntaxhighlighter table td, .syntaxhighlighter table tr, .syntaxhighlighter table tbody, .syntaxhighlighter table thead, .syntaxhighlighter table caption, .syntaxhighlighter textarea {',
            '        top: 6px !important;',
            '        height: 19px !important;',
            '    }',
            '}',
            '</style>'
        ]);
    }
});

美化工具栏(删除不必要的功能按钮 并增加宽高间距)

先来看2张对比效果:

before:

after:

想要达到以上的效果很简单, 有2种方法: 

1 初始化时指定item选项的值

2 直接修改kindeditor.js里面item的默认值

这里我毫不犹豫地选择了第二种方式 , 暴力修改
?
1
2
3
4
5
6
7
8
9
//第257行 修改为以下代码即可
items : [
    'source', '|', 'code', '|',
    'fontsize', 'forecolor', 'bold', '|',
    'image', 'multiimage', 'link', '|',
    'fontname', 'italic', 'underline', 'strikethrough', '|',
    'flash', 'media', 'insertfile', 'table', 'hr', 'baidumap', 'pagebreak', 'anchor', '|',
    'selectall', 'undo', 'redo'
],
修改完JS之后你以为就能舒服了么, nonono你现在只是将图标删除了而已, 还有样式也需要改, 那么进入Kindeditor/themes/default.css
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//434行 .ke-toolbar-icon 修改样式:
{
    margin: 3px auto;
}
 
//444行 .ke-toolbar .ke-outline 增加样式:
{
    box-sizing: border-box;
    width: 38px;
    height: 25px;
}
 
//459行 .ke-toolbar .ke-separator 修改样式:
{
    margin: 6px 3px 5px;
}

行数可能会稍有偏差, 根据选择器修改指定内容即可, 修改完之后你就可以舒服了~

七 编辑页初始高度自适应 && 工具栏根据滚动条智能定位

高度自适应

当进入编辑页时, 编辑器里是有内容的, 内容高度比编辑器的初始高度高很多, 此时还需要自己手动去拉伸textarea不是很麻烦?

虽然用全屏模式不会有此问题, 但是全屏模式编写文章时看到的样式和发布文章之后去文章页看到的样式差距会很大(因为宽度不一样)

所以我不用全屏模式, 解决这个问题也很简单, 我写了一个定时器监听文本高度, 等待初始化完成之后直接改变编辑器高度即可
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.onload = function(){
    function ifChg(){
        var k = document.getElementsByClassName('ke-edit')[0];
        if(k && k.style.height){
            clearInterval(ift);
            var f = k.firstElementChild;
            var b = f.contentWindow.document.querySelector('.ke-content').offsetHeight + 50;
            var x = k.lastElementChild;
            k.style.height = b + 'px';
            f.style.height = b + 'px';
            x.style.height = b - 2 + 'px';
        }
    }
    var ift = setInterval(ifChg, 300);
};

工具栏智能定位

当我的文本内容很多, 高度非常高的时候, 滚动条需要拉很远才能到最底部, 此时工具栏是固定在编辑器最上方

那我需要将底部文字小小地加个粗岂不是都要拉滚动条拉个2分钟才能加到? 然后加完再拉个2分钟拉回底部?

所以为了解决这个问题, 我加了一个滚动条监听事件

当滚动条到达工具栏的高度时, 工具栏定位就固定在屏幕上方, 也就是position: fixed;
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function C(e, a){ return a ? document.getElementsByClassName(e) : document.getElementsByClassName(e)[0]; }
function getTop(e){
    var t = 0;
    while(e.nodeName !== 'BODY'){
        t += e.offsetTop;
        e = e.offsetParent;
    }
    return t;
}
KindEditor.ready(function(K) {
    var s = true, t = getTop(C('ke-container')), c = C('ke-toolbar'), d = true;
    function onScroll(){
        if(s){
            requestAnimationFrame(relFun);
            s = false;
        }
    }
    function relFun(){
        if(pageYOffset >= t){
            if(d){
                c.classList.add('toFix');
                d = false;
            }
        }else{
            if(!d){
                c.classList.remove('toFix');
                d = true;
            }
        }
        s = true;
    }
    window.addEventListener('scroll',onScroll,false);
});
//scroll监听事件绑定到DOM加载完成事件上(kindEditor.ready) , 如果你写了ready函数了, 那么你只需要将我的代码追加进去即可
//我只展示了实现智能定位这个功能的代码, CgetTop2个函数 是我经常用到的自定义函数, 功能就是类似于JQ$offset()
当然加了这段JS你还是不能舒服, 因为还缺少样式, 比如点击按钮的下拉栏是根据body定位的, 你也需要将其改为fixed定位
所以你还需要在Kindeditor/themes/default.css中做以下修改:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//537行  .ke-menu  增加样式
{
    position: fixed !important;
    left: 640px !important;
    top: 167px !important;
}
 
//596行  .ke-colorpicker 增加样式:
{
    position: fixed !important;
    left: 640px !important;
    top: 167px !important;
}
 
//新增class:
.toFix{
    position: fixed;
    top: 136px;
    box-shadow: 0 0 10px #5b5b5b;
    border: 0;
}
CSSJS配合使用, 这次就真滴舒服了, 阔以来看看修改完后的效果:

以上只展示了我的编辑器的部分功能 , 更多的功能代码都放在了我的github上~感兴趣的童鞋阔以去下载 : gayhub传送门

发布评论
评论
共计 1条评论
最新评论
2017-12-06 11:02:26Xrunnoob[中国河南省郑州市网友]
赞一个
1
4
回复