夜间样式已开启,点击 关闭 夜间样式
夜间样式已关闭取消

Copy As HTML From VSCode

 

JS生成可自定义语法高亮HTMLcode

cnblogs @ Orcim   


 

 

 

 


!deprecated!

这里有更好的方案,具体看我的这篇博客👉博客代码高亮的另一种思路👈


这篇文章介绍了如何在博客里插入一段 pretty 代码框的方法(以博客园为例),主要是因为实在是受不了博客园以及其他一些博客自带代码框的样子了w~

这篇文章很长很长,你可以直接点击这里,直接跳到源代码处,复制代码,或者滑到文章最底部查看使用方法。

 理是利用 VSCode Copy With Syntax Highlighting 这个自带的功能,其实很多 IDE 都具有此类功能:

Ctrl + 逗号,打开设置,搜索找到上图中的选项就可以开启高亮语法复制为 HTML 代码的这个功能了,当然现在直接粘贴并不能直接获取到 剪切板内 TEXT 文本,也无法获取带高亮样式的内 HTML 文本。

其实是可以获取剪切板的 HTML 文本的,js 提供了一个 onpaste 事件,可以在函数事件的 event 参数中获取到剪切板的内容了。

 

event.clipboardData.getData( Format: String )

 如果要获取剪切板的纯文本,String 为 “text/plan”,如果是 HTML 文本,String 为 “text/html”:

12345
document.onpaste = function (e){
    var cb_data = e.clipboardData.getData("text\/html");
    // var cb_data = e.clipboardData.getData("text\/plain");
    console.log(cb_data);
}
 

然后,在 IDE 里面复制一段高亮显示着的代码,浏览器里面 Ctrl + V,控制台会 log 出来一堆东西:

 

为方便查看把这串从 VSCode剪切板 里面得到的内容 Prettify 一下,其实很有规律:

12345678910111213141516171819
<!--StartFragment-->
<div style="color: #d4d4d4;background-color: #1e1e1e;font-family: Meslo LG L DZ, Microsoft YaHei;font-weight: 200;font-size: 16px;line-height: 34px;white-space: pre;">
    <div>
        <span style="color: #9cdcfe;">document</span>
        <span style="color: #d4d4d4;">.</span>
        <span style="color: #dcdcaa;">onpaste</span>
        <span style="color: #d4d4d4;"> = </span>
        <span style="color: #569cd6;">function</span>
        <span style="color: #d4d4d4;"> (</span>
        <span style="color: #9cdcfe;">e</span>
        <span style="color: #d4d4d4;">){</span>
    </div>
    <div>
        <span style="color: #d4d4d4;">    </span>
        <span style="color: #569cd6;">var</span>
        ........
    </div>
</div>
<!--EndFragment-->
 

 可能你也发现了规律了吧,其实这就是大多数 IDE 的语法高亮显示功能的原理,整个编辑器就相当于浏览器的窗口,窗口中每段文字都被特定样式的标签包裹起来……每行一个 div 又包裹很多 span 的行内元素,就这样一行一行堆砌,然后就实现了这个功能。

得到的这些 HTML 文本基本上就可以复制到各大博客的编辑器来用了,但是我们除了去设置整个编辑器的样式这个方法之外,没有其他更简便的办法去改变高亮的样式了,而且如果剪切板中 HTML 标签内为 制表符或者是一些空白字符的话,编辑器通常会将其忽略,就没有代码缩进显示,比如我在博客园的编辑器中直接复制 CODE02 的代码到 HTML 编辑文本域里面,代码的缩进全部都没有了,于是就想到对这些剪切板里面的内容处理一下,可以灵活输出自己想要展示 Code 的 HTML。

于是花了一天的时间,从最初的 HTML模板布局 到整个功能的实现,以及 JS 代码修改,最后完善了整个程序。直接给大家看 demo,其实前面的代码框就是演示……,上面的两个代码展示框就是 JS 生成的(普通的字符串的处理),加入了行数标识以及标题标识功能,之后还添加了一个 light 主题,两者样式兼容移动端:

12345678910111213141516
var themes = {
    "dark": {
        c_title_bg: "#252525"
        c_title_fg: "#ededed",
        c_editor_bg: "#1e1e1e",
        c_sideNum_bg: "#1e1e1e",
        c_sideNum_fg: "#727272"
    }, 
    "light": {
        c_title_bg: "#dcdcdc"
        c_title_fg: "#999",
        c_editor_bg: "#f5f5f5",
        c_sideNum_bg: "#e5e5e5",
        c_sideNum_fg: "#999"
    }
};
 

 这里就不卖关子了,直接贴代码吧,里面有注释。

-(紧凑的分割线)-

源代码

HTML 代码,便于最后的自定义样式的代码框输出

12345678910111213141516171819202122232425262728293031323334353637
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CopyAsHtmlFromVScode</title>
</head>
<body>
    <div id="codePart">
        <div id="codeBox" style='width: 100%; height: auto; line-height: 34px; position: relative; font-family: "Meslo LG L DZ", "monospace";'>
            <!-- 标题一栏 -->
            <div id="banner" style="width: 100%; height: 34px; position: absolute; top: 0; left: 0; background: rgba(0, 0, 0, .1); border-top-left-radius: 8px; border-top-right-radius: 8px; box-sizing: border-box; border-bottom: 1px solid rgba(0, 0, 0, .15)">
                <!-- 
                    生成的代码框左上角用于标识文件类型的圆,颜色集合变量名:stampColors
                    html -> 红
                    css -> 蓝
                    js -> 黄
                    txt -> 黑灰
                 -->
                <div id="bannerStamp" style="height: 34px; width: 34px; float: left; display: flex; align-items: center; justify-content: center"><span style="display: block; width: 60%; height: 60%; -webkit-border-radius: 50%; background: green">&nbsp;</span></div>
                <!-- 标题名 -->
                <div style="height: 34px; float: left; font-size: 16px; line-height: 34px; display: flex; align-items: center;"><span style="display: block; font-family: sans-serif" id="bannerTitle">123.html</span></div>
            </div>
            <div class="side" id="vsSide" style="width: 50px; background: none; float: left; padding: 40px 0 30px; background: #f5f5f5; border-top-left-radius: 8px; border-bottom-left-radius: 8px;">
                <!-- 侧边行数一列 -->
            </div>
            <div id="containerOuter" style="width: calc(100% - 70px); float: left; white-space: nowrap; background: #f5f5f5; overflow: auto; padding: 40px 0 30px 20px; border-bottom-right-radius: 8px; border-top-right-radius: 8px;">
                <!-- 代码高亮的展示 HTML -->
                <div id="_containerBox"></div>
            </div>
                <!-- 防止高度坍塌 -->
            <div style="clear: both;"></div>
        </div>
    </div>
</body>
</html>
 

JS 代码,直接复制放在 body 标签后的 script 标签里面,这里分开展示是为了方便排版和阅读~

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
var themes = { // 主题,自己定义了两种,可以自己加~
    "dark": {
        c_title_bg: "#252525"// 标题栏背景色
        c_title_fg: "#ededed"// 前景色(文字颜色)
        c_editor_bg: "#1e1e1e"// 代码区背景
        c_sideNum_bg: "#1e1e1e"// 行数栏背景
        c_sideNum_fg: "#727272" // 前景色
    }, 
    "light": {
        c_title_bg: "#dcdcdc"
        c_title_fg: "#999",
        c_editor_bg: "#f5f5f5",
        c_sideNum_bg: "#e5e5e5",
        c_sideNum_fg: "#999"
    }
};
var config = { // 调整基本样式
    "theme": "dark"// 主题名
    "fontFamily": '"Meslo LG L DZ", "monospace"'
    "lineHeight": "25px",
    "fontSize": "15px",
    "fileName": "copyAsHTML.js"// 标题名称
    "stampColor": "" // 留空会根据文件拓展名设置圆点的颜色
};
document.onpaste = function(e){
    format(); // 初始化代码外框模板
    var cb_str = e.clipboardData.getData('text\/html'); // 获取从 VSCode 里面复制的含 html 标签的代码
    var tmpDiv = document.createElement("div");
    tmpDiv.innerHTML = cb_str;
    var containerBox = tmpDiv.children[0];
 
    var arrLineDiv = containerBox.children;
    var HollowArr = [];
    for(var i=0i<arrLineDiv.lengthi++){
        var arrLineSpanChar = arrLineDiv[i].children;
        var tmp_arrLine = [];
        for(var j=0j<arrLineSpanChar.lengthj++){
            var arrEmpty = [];
            arrEmpty[0] = arrLineSpanChar[j].style.color;
            // 空格替换为 HTML 转义符
            arrEmpty[1] = arrLineSpanChar[j].innerHTML.replace(/ /g"&nbsp;");
            tmp_arrLine.push(arrEmpty);
        }
        HollowArr.push(tmp_arrLine);
    }
 
    var _containerBox = document.getElementById("_containerBox");
    var _sideNums = document.getElementById("vsSide");
    for(var l=0l<HollowArr.lengthl++){
        _containerBox.append(returnLine(HollowArr[l]));
        var tmpSpan = returnSpan(""l+1);
        tmpSpan.style = "display: block; width: 40px; text-align: right; padding-right: 10px; float: left; font-size: 14px; height: " + config.lineHeight;
        _sideNums.append(tmpSpan);
    }
    var g_Span = _sideNums.querySelectorAll("span");
    if(_sideNums.innerHTMLg_Span[g_Span.length - 1].style.borderBottomRightRadius = "4px";
    // 最终结果在浏览器控制台处输出查看
    console.log(document.getElementById("codePart").innerHTML); 
 
    function returnLine(array){
        var oDiv = document.createElement("div");
        oDiv.style = "height: " + config.lineHeight + "; line-height: " + config.lineHeight + "; font-size: " + config.fontSize + ";";
        for(var k=0k<array.lengthk++){
            tspan = returnSpan(array[k][0], array[k][1]);
            tspan.style.lineHeight = "100%";
            oDiv.append(tspan);
        }
        var groupSpan = oDiv.querySelectorAll("span");
        if(oDiv.innerHTMLgroupSpan[groupSpan.length - 1].style.paddingRight = "20px";
        return oDiv;
    }
    function returnSpan(crct){
        var oSpan = document.createElement("span");
        oSpan.innerHTML = ct;
        if(!crreturn oSpan;
        oSpan.style.color = cr;
        return oSpan;
    } 
    function format(){
        var stampColors = { // 左上角圆点颜色主题集合
            "html": "#d13239"
            "css": "#4286f4"
            "js": "#fbb507"
            "txt": "#303030"
        }
        var oCodeBox = document.getElementById("codeBox");
        var oBanner = document.getElementById("banner");
        var bannerStamp = document.getElementById("bannerStamp");
        var bannerTitle = document.getElementById("bannerTitle");
        var oVsSide = document.getElementById("vsSide");
        var oOuter = document.getElementById("containerOuter");
        var theStampColor = config.stampColor;
        var configTheme = config.theme;
 
        if(!config.stampColortheStampColor = stampColors[config.fileName.split(".").pop()];
        oCodeBox.style.fontFamily = config.fontFamily;
        oCodeBox.style.lineHeight = config.lineHeight;
        bannerTitle.innerText = config.fileName;
        bannerStamp.querySelector("span").style.backgroundColor = theStampColor;
        oBanner.style.backgroundColor = themes[configTheme].c_title_bg;
        bannerTitle.style.color = themes[configTheme].c_title_fg;
        oOuter.style.backgroundColor = themes[configTheme].c_editor_bg;
        oVsSide.style.backgroundColor = themes[configTheme].c_sideNum_bg;
        oVsSide.style.color = themes[configTheme].c_sideNum_fg;
    }
}
 

使用方法

  1. 在 copyAsHTML.html 中引入 copyAsHTML.js
  2. 打开 VSCode,并在设置中确保已勾选 控制在复制时是否同时复制语法高亮 选项
  3. Ctrl + C 复制一段编辑器的代码
  4. Chrome 打开 copyAsHTML.html,页面空白区 Ctrl + V 粘贴
  5. F12 打开 控制台,Copy 输出的所有内容
  6. 粘贴 HTML 代码到 HTML 编辑器中,即可

 

Advance

添加复制功能和展开/收起功能:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CopyAsHtmlFromVScode</title>
    <style>
    </style>
</head>
<body>
    <div id="codePart">
        <div id="codeBox" class="codeBox" style='width: 100%; height: auto; line-height: 34px; position: relative; font-family: "Meslo LG L DZ", "monospace";'>
            <div id="banner" class="banner" style="width: 100%; height: 34px; position: absolute; top: 0; left: 0; background: rgba(0, 0, 0, .1); border-top-left-radius: 8px; border-top-right-radius: 8px; box-sizing: border-box; border-bottom: 1px solid rgba(0, 0, 0, .15)">
                <div id="bannerStamp" style="height: 34px; width: 34px; float: left; display: flex; align-items: center; justify-content: center">
                    <span style="display: block; width: 60%; height: 60%; border-radius: 50%; background: green">&nbsp;</span>
                </div>
                <div style="height: 34px; float: left; font-size: 16px; line-height: 34px; display: flex; align-items: center;">
                    <span style="display: block; font-family: sans-serif" id="bannerTitle">123.html</span>
                </div>
                <div style="height: 34px; float: right; font-size: 16px; line-height: 34px; display: flex; align-items: center; justify-content: center;">
                    <span style="display: block; background: rgba(255, 255, 255, .65); font-family: sans-serif; padding: 0 5px; margin-right: 10px;" data-clipboard-target="">COPY</span>
                    <span class="expandBtn" style="display: block; background: rgba(255, 0, 0, .65); color: #f5f5f5; font-family: sans-serif; padding: 0 5px; margin-right: 10px;">EXPAND</span>
                </div>
            </div>
            <div class="side" id="vsSide" style="width: 50px; background: none; float: left; padding: 40px 0 30px; background: #f5f5f5; border-top-left-radius: 8px; border-bottom-left-radius: 8px;">
            </div>
            <div id="containerOuter" style="width: calc(100% - 70px); float: left; white-space: nowrap; background: #f5f5f5; overflow: auto; padding: 40px 0 30px 20px; border-bottom-right-radius: 8px; border-top-right-radius: 8px;">
                <div id="_containerBox">
 
                </div>
            </div>
            <div style="clear: both;">
            </div>
        </div>
    </div>
</body>
</html>
<script src="./clipBoard.js"></script>
<script>
var themes = { // 主题,自己定义了两种,可以自己加~
    "dark": {
        c_title_bg: "#252525", // 标题栏背景色
        c_title_fg: "#ededed", // 前景色(文字颜色)
        c_editor_bg: "#1e1e1e", // 代码区背景
        c_sideNum_bg: "#1e1e1e", // 行数栏背景
        c_sideNum_fg: "#727272" // 前景色
    }, 
    "light": {
        c_title_bg: "#dcdcdc", 
        c_title_fg: "#999",
        c_editor_bg: "#f5f5f5",
        c_sideNum_bg: "#e5e5e5",
        c_sideNum_fg: "#999"
    }
};
var config = { // 调整基本样式
    "theme": "dark", // 主题名
    "fontFamily": '"Meslo LG L DZ", "monospace"', 
    "lineHeight": "25px",
    "fontSize": "15px",
    "fileName": "advancedHighLight.html", // 标题名称
    "stampColor": "", // 留空会根据文件拓展名设置圆点的颜色
    "maxHeight": 400, // 限制高度,px
    "highLight": [true"#569cd6"]
};
 
/* 兼容 IE, getComputedStyle */
if (!window.getComputedStyle) {
    window.getComputedStyle = function(el, pseudo) {
        this.el = el;
        this.getPropertyValue = function(prop) {
            var re = /(\-([a-z]){1})/g;
            if (prop == 'float') prop = 'styleFloat';
            if (re.test(prop)) {
                prop = prop.replace(re, function () {
                    return arguments[2].toUpperCase();
                });
            }
            return el.currentStyle[prop] ? el.currentStyle[prop] : null;
        }
        return this;
    }
};
document.onpaste = function(e){
    format(); // 初始化代码外框模板
    var cb_str = e.clipboardData.getData('text\/html') || e.clipboardData.getData('text\/plain'); // 获取从 VSCode 里面复制的含 html 标签的代码
    console.log(cb_str)
    var tmpDiv = document.createElement("div");
    tmpDiv.innerHTML = cb_str;
    var containerBox = tmpDiv.children[0];
 
    var arrLineDiv = containerBox.children;
    var HollowArr = [];
    for(var i=0; i<arrLineDiv.length; i++){
        var arrLineSpanChar = arrLineDiv[i].children;
        var tmp_arrLine = [];
        for(var j=0; j<arrLineSpanChar.length; j++){
            var arrEmpty = [];
            arrEmpty[0] = arrLineSpanChar[j].style.color;
            // 空格替换为 HTML 转义符
            arrEmpty[1] = arrLineSpanChar[j].innerHTML.replace(/ /g, "&nbsp;");
            tmp_arrLine.push(arrEmpty);
        }
        HollowArr.push(tmp_arrLine);
    }
 
    var _containerBox = document.getElementById("_containerBox");
    var stamp = new Date().getTime();
    _containerBox.id = "d" + stamp;
    document.querySelector("[data-clipboard-target]").dataset.clipboardTarget = "#d" + stamp;
    var _sideNums = document.getElementById("vsSide");
    for(var l=0; l<HollowArr.length; l++){
        _containerBox.append(returnLine(HollowArr[l]));
        var tmpSpan = returnSpan("", l+1);
        tmpSpan.style = "display: block; width: 40px; text-align: right; padding-right: 10px; float: left; font-size: 14px; height: " + config.lineHeight;
        _sideNums.append(tmpSpan);
    }
    var g_Span = _sideNums.querySelectorAll("span");
    if(_sideNums.innerHTML) g_Span[g_Span.length - 1].style.borderBottomRightRadius = "4px";
    
    var cb = document.getElementById("codeBox");
    var codeHeight = parseFloat(window.getComputedStyle(codeBox, "").getPropertyValue("height"));
    console.log(codeHeight)
    var expandBtn = document.querySelector(".expandBtn");
    var tog = {
        "expand": function(){
            document.getElementById("banner").style.borderTopRightRadius = "8px";
            // cb.style.maxHeight = codeHeight + "px";
            cb.style.overflow = "auto";
            return "SHRINK";
        },
        "shrink": function(){
            document.getElementById("banner").style.borderTopRightRadius = 0;
            // cb.style.maxHeight = config.maxHeight + "px";
            cb.style.overflow = "auto";
            return "EXPAND";
        }
    };
    if(codeHeight > config.maxHeight){
        expandBtn.style.display = "block";
        tog["shrink"]();
        expandBtn.onclick = function(){
            var lbl = this.innerHTML;
            this.innerHTML = (lbl === "EXPAND" ? tog["expand"]() : tog["shrink"]());
        }
    }else{
        expandBtn.style.display = "none";
    }
    // 最终结果在看控制台处输出查看
    console.log(document.getElementById("codePart").innerHTML); 
 
    function returnLine(array){
        var oDiv = document.createElement("div");
        var bFill = config.highLight[0];
        oDiv.style = "height: " + config.lineHeight + "; line-height: " + config.lineHeight + "; font-size: " + config.fontSize + ";";
        if(!bFill) oDiv.style.color = config.highLight[1];
        for(var k=0; k<array.length; k++){
            tspan = returnSpan(array[k][0], array[k][1], bFill);
            tspan.style.lineHeight = "100%";
            oDiv.append(tspan);
        }
        var groupSpan = oDiv.querySelectorAll("span");
        if(oDiv.innerHTML) groupSpan[groupSpan.length - 1].style.paddingRight = "20px";
        return oDiv;
    }
    function returnSpan(cr, ct, fill = true){
        var oSpan = document.createElement("span");
        oSpan.innerHTML = ct;
        if(!cr) return oSpan;
        if(fill) oSpan.style.color = cr;
        return oSpan;
    } 
    function format(){
        var stampColors = { // 左上角圆点颜色主题集合
            "html": "#d13239", 
            "css": "#4286f4", 
            "js": "#fbb507", 
            "txt": "#373a41", 
            "plist": "#8bc34a"
        }
        var oCodeBox = document.getElementById("codeBox");
        var oBanner = document.getElementById("banner");
        var bannerStamp = document.getElementById("bannerStamp");
        var bannerTitle = document.getElementById("bannerTitle");
        var oVsSide = document.getElementById("vsSide");
        var oOuter = document.getElementById("containerOuter");
        var theStampColor = config.stampColor;
        var configTheme = config.theme;
 
        if(config.maxHeight){
            oCodeBox.dataset.maxHeight = config.maxHeight;
        };
        if(!config.stampColor) theStampColor = stampColors[config.fileName.split(".").pop()];
        oCodeBox.style.fontFamily = config.fontFamily;
        oCodeBox.style.lineHeight = config.lineHeight;
        bannerTitle.innerText = config.fileName;
        bannerStamp.querySelector("span").style.backgroundColor = theStampColor;
        oBanner.style.backgroundColor = themes[configTheme].c_title_bg;
        bannerTitle.style.color = themes[configTheme].c_title_fg;
        oOuter.style.backgroundColor = themes[configTheme].c_editor_bg;
        oVsSide.style.backgroundColor = themes[configTheme].c_sideNum_bg;
        oVsSide.style.color = themes[configTheme].c_sideNum_fg;
    }
}
new ClipboardJS('[data-clipboard-target]');
 
</script>
 

 

Advance Ver2.0

增加代码框盒子bottom处的复制按钮和展开/收起按钮。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>CopyAsHtmlFromVScode</title>
    <style>
    </style>
</head>
<body>
    <div id="codePart">
        <div id="codeBox" class="codeBox" style='width: 100%; height: auto; line-height: 34px; position: relative; font-family: "Meslo LG L DZ", "monospace";'>
            <div id="banner" class="banner" style="width: 100%; height: 34px; position: absolute; top: 0; left: 0; background: rgba(0, 0, 0, .1); border-top-left-radius: 8px; border-bottom-left-radius: 8px; box-sizing: border-box; border-bottom: 1px solid rgba(0, 0, 0, .15)">
                <div id="bannerStamp" style="height: 34px; width: 34px; float: left; display: flex; align-items: center; justify-content: center">
                    <span style="display: block; width: 60%; height: 60%; border-radius: 50%; background: green">&nbsp;</span>
                </div>
                <div style="height: 34px; float: left; font-size: 16px; line-height: 34px; display: flex; align-items: center;">
                    <span style="display: block; font-family: sans-serif" id="bannerTitle">123.html</span>
                </div>
                <div style="height: 34px; float: right; font-size: 16px; line-height: 34px; display: flex; align-items: center; justify-content: center;">
                    <span style="display: block; background: rgba(255, 255, 255, .65); font-family: sans-serif; padding: 0 5px; margin-right: 10px;" data-clipboard-target="">COPY</span>
                    <span class="expandBtn" style="display: block; background: rgba(255, 0, 0, .65); color: #f5f5f5; font-family: sans-serif; padding: 0 5px; margin-right: 10px;">EXPAND</span>
                </div>
            </div>
            <div class="side" id="vsSide" style="width: 50px; background: none; float: left; padding: 40px 0 45px; background: #f5f5f5; border-top-left-radius: 8px; border-bottom-left-radius: 8px;">
            </div>
            <div id="containerOuter" style="width: calc(100% - 70px); float: left; white-space: nowrap; background: #f5f5f5; overflow: auto; padding: 40px 0 45px 20px; border-bottom-right-radius: 8px; border-top-right-radius: 8px;">
                <div id="_containerBox">
 
                </div>
            </div>
            <div class="banner" style="width: 100%; height: 34px; position: absolute; bottom: 55px; left: 0; box-sizing: border-box; border-bottom: 1px solid rgba(0, 0, 0, .15)">
                <div style="height: 34px; float: right; font-size: 16px; line-height: 34px; display: flex; align-items: center; justify-content: center;">
                    <span style="display: block; background: rgba(255, 255, 255, .65); font-family: sans-serif; padding: 0 5px; margin-right: 10px;" data-clipboard-target="">COPY</span>
                    <span class="expandBtn" style="display: block; background: rgba(255, 0, 0, .65); color: #f5f5f5; font-family: sans-serif; padding: 0 5px; margin-right: 10px;">EXPAND</span>
                </div>
            </div>
            <div style="clear: both;">
            </div>
        </div>
    </div>
</body>
</html>
<script src="./clipBoard.js"></script>
<script>
var themes = { // 主题,自己定义了两种,可以自己加~
    "dark": {
        c_title_bg: "#252525", // 标题栏背景色
        c_title_fg: "#ededed", // 前景色(文字颜色)
        c_editor_bg: "#1e1e1e", // 代码区背景
        c_sideNum_bg: "#1e1e1e", // 行数栏背景
        c_sideNum_fg: "#727272" // 前景色
    }, 
    "light": {
        c_title_bg: "#dcdcdc", 
        c_title_fg: "#999",
        c_editor_bg: "#f5f5f5",
        c_sideNum_bg: "#e5e5e5",
        c_sideNum_fg: "#999"
    }
};
var config = { // 调整基本样式
    "theme": "dark", // 主题名
    "fontFamily": '"Meslo LG L DZ", "monospace"', 
    "lineHeight": "25px",
    "fontSize": "15px",
    "fileName": "advancedHighLight_ver_2_0.html", // 标题名称
    "stampColor": "", // 留空会根据文件拓展名设置圆点的颜色
    "maxHeight": 400, // 限制高度,px
    "highLight": [true"#569cd6"]
};
 
/* 兼容 IE, getComputedStyle */
if (!window.getComputedStyle) {
    window.getComputedStyle = function(el, pseudo) {
        this.el = el;
        this.getPropertyValue = function(prop) {
            var re = /(\-([a-z]){1})/g;
            if (prop == 'float') prop = 'styleFloat';
            if (re.test(prop)) {
                prop = prop.replace(re, function () {
                    return arguments[2].toUpperCase();
                });
            }
            return el.currentStyle[prop] ? el.currentStyle[prop] : null;
        }
        return this;
    }
};
document.onpaste = function(e){
    format(); // 初始化代码外框模板
    var cb_str = e.clipboardData.getData('text\/html') || e.clipboardData.getData('text\/plain'); // 获取从 VSCode 里面复制的含 html 标签的代码
    console.log(cb_str)
    var tmpDiv = document.createElement("div");
    tmpDiv.innerHTML = cb_str;
    var containerBox = tmpDiv.children[0];
 
    var arrLineDiv = containerBox.children;
    var HollowArr = [];
    for(var i=0; i<arrLineDiv.length; i++){
        var arrLineSpanChar = arrLineDiv[i].children;
        var tmp_arrLine = [];
        for(var j=0; j<arrLineSpanChar.length; j++){
            var arrEmpty = [];
            arrEmpty[0] = arrLineSpanChar[j].style.color;
            // 空格替换为 HTML 转义符
            arrEmpty[1] = arrLineSpanChar[j].innerHTML.replace(/ /g, "&nbsp;");
            tmp_arrLine.push(arrEmpty);
        }
        HollowArr.push(tmp_arrLine);
    }
 
    var _containerBox = document.getElementById("_containerBox");
    var stamp = new Date().getTime();
    _containerBox.id = "d" + stamp;
    var clipBoard_tars = document.querySelectorAll("[data-clipboard-target]");
    for(var c=0; c<clipBoard_tars.length; c++) clipBoard_tars[c].dataset.clipboardTarget = "#d" + stamp;
    var _sideNums = document.getElementById("vsSide");
    for(var l=0; l<HollowArr.length; l++){
        _containerBox.append(returnLine(HollowArr[l]));
        var tmpSpan = returnSpan("", l+1);
        tmpSpan.style = "display: block; width: 40px; text-align: right; padding-right: 10px; float: left; font-size: 14px; height: " + config.lineHeight;
        _sideNums.append(tmpSpan);
    }
    var g_Span = _sideNums.querySelectorAll("span");
    if(_sideNums.innerHTML) g_Span[g_Span.length - 1].style.borderBottomRightRadius = "4px";
    
    var cb = document.getElementById("codeBox");
    var codeHeight = parseFloat(window.getComputedStyle(codeBox, "").getPropertyValue("height"));
    console.log(codeHeight)
    var expandBtn = document.querySelector(".expandBtn");
    var tog = {
        "expand": function(){
            document.getElementById("banner").style.borderTopRightRadius = "8px";
            // cb.style.maxHeight = codeHeight + "px";
            cb.style.overflow = "auto";
            return "SHRINK";
        },
        "shrink": function(){
            document.getElementById("banner").style.borderTopRightRadius = 0;
            // cb.style.maxHeight = config.maxHeight + "px";
            cb.style.overflow = "auto";
            return "EXPAND";
        }
    };
    if(codeHeight > config.maxHeight){
        expandBtn.style.display = "block";
        tog["shrink"]();
        expandBtn.onclick = function(){
            var lbl = this.innerHTML;
            this.innerHTML = (lbl === "EXPAND" ? tog["expand"]() : tog["shrink"]());
        }
    }else{
        expandBtn.style.display = "none";
    }
    // 最终结果在看控制台处输出查看
    console.log(document.getElementById("codePart").innerHTML); 
 
    function returnLine(array){
        var oDiv = document.createElement("div");
        var bFill = config.highLight[0];
        oDiv.style = "height: " + config.lineHeight + "; line-height: " + config.lineHeight + "; font-size: " + config.fontSize + ";";
        if(!bFill) oDiv.style.color = config.highLight[1];
        for(var k=0; k<array.length; k++){
            tspan = returnSpan(array[k][0], array[k][1], bFill);
            tspan.style.lineHeight = "100%";
            oDiv.append(tspan);
        }
        var groupSpan = oDiv.querySelectorAll("span");
        if(oDiv.innerHTML) groupSpan[groupSpan.length - 1].style.paddingRight = "20px";
        return oDiv;
    }
    function returnSpan(cr, ct, fill = true){
        var oSpan = document.createElement("span");
        oSpan.innerHTML = ct;
        if(!cr) return oSpan;
        if(fill) oSpan.style.color = cr;
        return oSpan;
    } 
    function format(){
        var stampColors = { // 左上角圆点颜色主题集合
            "html": "#d13239", 
            "css": "#4286f4", 
            "js": "#fbb507", 
            "txt": "#373a41", 
            "plist": "#8bc34a"
        }
        var oCodeBox = document.getElementById("codeBox");
        var oBanner = document.getElementById("banner");
        var bannerStamp = document.getElementById("bannerStamp");
        var bannerTitle = document.getElementById("bannerTitle");
        var oVsSide = document.getElementById("vsSide");
        var oOuter = document.getElementById("containerOuter");
        var theStampColor = config.stampColor;
        var configTheme = config.theme;
 
        if(config.maxHeight){
            oCodeBox.dataset.maxHeight = config.maxHeight;
        };
        if(!config.stampColor) theStampColor = stampColors[config.fileName.split(".").pop()];
        oCodeBox.style.fontFamily = config.fontFamily;
        oCodeBox.style.lineHeight = config.lineHeight;
        bannerTitle.innerText = config.fileName;
        bannerStamp.querySelector("span").style.backgroundColor = theStampColor;
        oBanner.style.backgroundColor = themes[configTheme].c_title_bg;
        bannerTitle.style.color = themes[configTheme].c_title_fg;
        oOuter.style.backgroundColor = themes[configTheme].c_editor_bg;
        oVsSide.style.backgroundColor = themes[configTheme].c_sideNum_bg;
        oVsSide.style.color = themes[configTheme].c_sideNum_fg;
    }
}
new ClipboardJS('[data-clipboard-target]');
 
</script>
 

 

posted @ 2019-01-18 00:20  Orcim  阅读(912)  评论(0编辑  收藏  举报