使用code-printer生成一份炫酷的简历

欢迎光临我的博客拓跋的前端客栈,这个是原文地址,这个是项目地址,欢迎star&fork。如果您发现我文章中存在错误,请尽情向我吐槽,大家一起学习一起进步φ(>ω<*)


DEMO


最终效果请点击这里,是不是有点意思?

code-printer.png

源码分析


code-printer的原理是首先搭起一个骨架,然后通过遍历的方式,一点一点地往骨架里塞东西。

骨架主要有三块:

  • <pre id="my-code">: 主要用来展示的HTML代码的,带标签
  • <style id="style-elem">: 主要填CSS代码的,用于把<pre>里特定的标签转换成特定的样式
  • <div id="script-area">: 主要是填JS代码的。但是由于一个字符一个字符往里面填代码会出现大量报错,因此这部分需要一个段落的JS代码全部书写完毕以后,通过一个命令符'~'来一次性填入。

printCodes

let printCodes = function (message, index, interval) {
    if (index < message.length) {
        $code_pre.scrollTop = $code_pre.scrollHeight;
        printChar(message[index++]);
        return setTimeout((function () {
            return printCodes(message, index, interval);
        }), speed);
    }
};

这段代码的主要作用就是遍历打印字符,同时每次打印的时候都将滚动条拖到最底下,保证用户能看到最新的变化。

printChar

let printChar = function (which) {
    let char, formatted_code, prior_block_match, prior_comment_match, script_tag;
    if (which === "`") {
        // 重置为空字符串,防止打印出来
        which = "";
        isJs = !isJs;
    }
    if (isJs) {
        if (which === "~" && !openComment) {
            script_tag = createElement("script");
            // two matches based on prior scenario
            prior_comment_match = /(?:\*\/([^\~]*))$/;
            prior_block_match = /([^~]*)$/;
            if (unformatted_code.match(prior_comment_match)) {
                script_tag.innerHTML = unformatted_code.match(prior_comment_match)[0].replace("*/", "") + "\n\n";
            } else {
                script_tag.innerHTML = unformatted_code.match(prior_block_match)[0] + "\n\n";
            }
            $script_area.innerHTML = "";
            $script_area.appendChild(script_tag);
        }
        char = which;
        formatted_code = jsHighlight($code_pre.innerHTML, char);
    } else {
        char = which === "~" ? "" : which;
        $style_elem.innerHTML += char;
        formatted_code = cssHighlight($code_pre.innerHTML, char);
    }
    prevAsterisk = which === "*";
    prevSlash = (which === "/") && !openComment;
    openInteger = which.match(/[0-9]/) || (openInteger && which.match(/[\.\%pxems]/)) ? true : false;
    if (which === '"') {
        openString = !openString;
    }
    unformatted_code += which;
    return $code_pre.innerHTML = formatted_code;
};

printChar函数是code-printer的核心函数,这个函数会根据当前的代码是JS还是CSS,来进行不同的处理。

如何判断是JS还是CSS代码呢?默认设置

let isJs = false;

也就是默认是CSS,然后以 ` 作为切换符号,每次遇到 ` 就切换一次语言。

当前字符属于JS时,在没遇到执行符号 ~ 之前,printChar只是单纯的打印格式化后的字符。遇到 ~ 以后,printChar进行了如下操作:

  1. 函数首先通过正则匹配,匹配出之前的JS整段代码。
  2. 再调用createElement()来创造一对<script></script>标签,用来存放JS代码。
  3. 然后将处理过的JS代码存入<script></script>标签内。
  4. 最后通过$script_area.appendChild()的方式将<script></script>及其内部的JS代码存入<div id="script-area">中。注意,每次调用$script_area.appendChild()之前,都要将之前<div id="script-area">清空一遍,防止之前的JS代码再执行一次。

当前字符属于CSS时,每次打印过程,一方面会将未格式化的字符串传入<style id="style-elem">中,用以生成样式。另一方面会将格式化的代码输出到<pre id="my-code">中,用以展示代码。

cssHighlightjsHighlight

这两个函数十分类似,主要作用就是通过正则匹配,给不同类型的字符两端封上不同的标签,用以高亮代码。举个栗子:

if (openInteger && !which.match(/[0-9\.]/) && !openString && !openComment) {
    s = string.replace(/([0-9\.]*)$/, "<em class=\"int\">$1</em>" + which);
}

这就是一处典型的匹配+替换标签组合拳。作用是代码在以数字结尾时,给数字两端封上<em class="int"></em>的标签。

代码中还有很多用作标志位的参数,比如说openInteger,表示这段输入都是数字。通过对这些控制位进行操作,可以将零散的字符分成一段一段的,方便进行处理。

其他部分就不谈了,自己可以看源代码,我已经加了备注。

使用方法


您可以fork过去直接修改,也可以按照如下步骤操作

git clone https://github.com/tuobaye0711/code-printer.git

安装依赖文件

npm install

打包文件

npm start

起服务

npm run server

修改配置说明:

resume 文件存放简历或者其他静态资源

source/code.js 存放需要打印并展示样式的代码(CSS/JS)

source/app.js 是主代码,可以修改一些比如说打印速度、高亮色等配置

小结


能在自己网站挂一份带打印特效的简历,想必能让人眼前一亮吧。这篇文章主要安利了一下我这个名为code-printer的小项目,希望能帮到各位~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,050评论 25 707
  • error code(错误代码)=0是操作成功完成。error code(错误代码)=1是功能错误。error c...
    Heikki_阅读 3,378评论 1 9
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,145评论 0 13
  • 怎样爱一个人,在不同时期会有不同体悟。 年少时初喜欢一个人,觉得特别神圣,很伟大,却又懵懂无知,不知道做些什么好,...
    彦希妈阅读 354评论 2 1
  • @font-family为样式表添加字体,通过指定字体的下载地址。 @font-family{ font-fami...
    猿分让我们相遇阅读 212评论 0 0