[js] 网页输入框打字特效(懒人版)

一个可用于博客的 JavaScript 网页输入框打字特效

Head Pic: 「空の境界×Fate/GO コラボ記念」/「冬ゆき」のイラスト [pixiv]

网页输入框打字特效(js)

具体效果见本博客评论输入打字效果

如何使用

直接下载 这个js脚本 放到网站的某个位置,然后在博客的 footer 模板中引用即可,无需再添加任何额外代码。

<!-- In footer.php -->
<script type="text/javascript" src="(这个脚本的路径)"></script>
这个 JavaScript 脚本已经经过混淆压缩,相比原版脚本更节省流量。
请务必在 footer,即网页模板中 body 的末尾位置引用!
如果在 header 中引用会有找不到 body 的错误。

源码(未压缩混淆)

(function webpackUniversalModuleDefinition(root, factory) {
    if (typeof exports === 'object' && typeof module === 'object') module.exports = factory();
    else if (typeof define === 'function' && define.amd) define([], factory);
    else if (typeof exports === 'object') exports["POWERMODE"] = factory();
    else root["POWERMODE"] = factory()
})(this, function() {
    return (function(modules) {
        var installedModules = {};
        function __webpack_require__(moduleId) {
            if (installedModules[moduleId]) return installedModules[moduleId].exports;
            var module = installedModules[moduleId] = {
                exports: {},
                id: moduleId,
                loaded: false
            };
            modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
            module.loaded = true;
            return module.exports
        }
        __webpack_require__.m = modules;
        __webpack_require__.c = installedModules;
        __webpack_require__.p = "";
        return __webpack_require__(0)
    })([function(module, exports, __webpack_require__) {
            'use strict';
            var canvas = document.createElement('canvas');
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999';
            window.addEventListener('resize', function() {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight
            });
            document.body.appendChild(canvas);
            var context = canvas.getContext('2d');
            var particles = [];
            var particlePointer = 0;
            var frames = 120;
            var framesRemain = frames;
            var rendering = false;
            POWERMODE.shake = true;

            function getRandom(min, max) {
                return Math.random() * (max - min) + min
            }
            function getColor(el) {
                if (POWERMODE.colorful) {
                    var u = getRandom(0, 360);
                    return 'hsla(' + getRandom(u - 10, u + 10) + ', 100%, ' + getRandom(50, 80) + '%, ' + 1 + ')'
                } else {
                    return window.getComputedStyle(el).color
                }
            }
            function getCaret() {
                var el = document.activeElement;
                var bcr;
                if (el.tagName === 'TEXTAREA' || (el.tagName === 'INPUT' && el.getAttribute('type') === 'text')) {
                    var offset = __webpack_require__(1)(el, el.selectionStart);
                    bcr = el.getBoundingClientRect();
                    return {
                        x: offset.left + bcr.left,
                        y: offset.top + bcr.top,
                        color: getColor(el)
                    }
                }
                var selection = window.getSelection();
                if (selection.rangeCount) {
                    var range = selection.getRangeAt(0);
                    var startNode = range.startContainer;
                    if (startNode.nodeType === document.TEXT_NODE) {
                        startNode = startNode.parentNode
                    }
                    bcr = range.getBoundingClientRect();
                    return {
                        x: bcr.left,
                        y: bcr.top,
                        color: getColor(startNode)
                    }
                }
                return {
                    x: 0,
                    y: 0,
                    color: 'transparent'
                }
            }
            function createParticle(x, y, color) {
                return {
                    x: x,
                    y: y,
                    alpha: 1,
                    color: color,
                    velocity: {
                        x: -1 + Math.random() * 2,
                        y: -3.5 + Math.random() * 2
                    }
                }
            }
            function POWERMODE() {
                {
                    var caret = getCaret();
                    var numParticles = 5 + Math.round(Math.random() * 10);
                    while (numParticles--) {
                        particles[particlePointer] = createParticle(caret.x, caret.y, caret.color);
                        particlePointer = (particlePointer + 1) % 500
                    }
                    framesRemain = frames;
                    if (!rendering) {
                        requestAnimationFrame(loop)
                    }
                } {
                    if (POWERMODE.shake) {
                        var intensity = 1 + 2 * Math.random();
                        var x = intensity * (Math.random() > 0.5 ? -1 : 1);
                        var y = intensity * (Math.random() > 0.5 ? -1 : 1);
                        document.body.style.marginLeft = x + 'px';
                        document.body.style.marginTop = y + 'px';
                        setTimeout(function() {
                            document.body.style.marginLeft = '';
                            document.body.style.marginTop = ''
                        }, 75)
                    }
                }
            };
            POWERMODE.colorful = false;

            function loop() {
                if (framesRemain > 0) {
                    requestAnimationFrame(loop);
                    framesRemain--;
                    rendering = true
                } else {
                    rendering = false
                }
                context.clearRect(0, 0, canvas.width, canvas.height);
                for (var i = 0; i < particles.length; ++i) {
                    var particle = particles[i];
                    if (particle.alpha <= 0.1) continue;
                    particle.velocity.y += 0.075;
                    particle.x += particle.velocity.x;
                    particle.y += particle.velocity.y;
                    particle.alpha *= 0.96;
                    context.globalAlpha = particle.alpha;
                    context.fillStyle = particle.color;
                    context.fillRect(Math.round(particle.x - 1.5), Math.round(particle.y - 1.5), 3, 3)
                }
            }
            requestAnimationFrame(loop);
            module.exports = POWERMODE
        }, function(module, exports) {
            (function() {
                var properties = ['direction', 'boxSizing', 'width', 'height',
                    'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth',
                    'borderBottomWidth', 'borderLeftWidth', 'borderStyle', 'paddingTop',
                    'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle',
                    'fontVariant', 'fontWeight', 'fontStretch', 'fontSize',
                    'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign',
                    'textTransform', 'textIndent', 'textDecoration', 'letterSpacing',
                    'wordSpacing', 'tabSize', 'MozTabSize'];
                var isFirefox = window.mozInnerScreenX != null;

                function getCaretCoordinates(element, position, options) {
                    var debug = options && options.debug || false;
                    if (debug) {
                        var el = document.querySelector('#input-textarea-caret-position-mirror-div');
                        if (el) {
                            el.parentNode.removeChild(el)
                        }
                    }
                    var div = document.createElement('div');
                    div.id = 'input-textarea-caret-position-mirror-div';
                    document.body.appendChild(div);
                    var style = div.style;
                    var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;
                    style.whiteSpace = 'pre-wrap';
                    if (element.nodeName !== 'INPUT') style.wordWrap = 'break-word';
                    style.position = 'absolute';
                    if (!debug) style.visibility = 'hidden';
                    properties.forEach(function(prop) {
                        style[prop] = computed[prop]
                    });
                    if (isFirefox) {
                        if (element.scrollHeight > parseInt(computed.height)) style.overflowY = 'scroll'
                    } else {
                        style.overflow = 'hidden'
                    }
                    div.textContent = element.value.substring(0, position);
                    if (element.nodeName === 'INPUT') div.textContent = div.textContent.replace(/\s/g, "\u00a0");
                    var span = document.createElement('span');
                    span.textContent = element.value.substring(position) || '.';
                    div.appendChild(span);
                    var coordinates = {
                        top: span.offsetTop + parseInt(computed['borderTopWidth']),
                        left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
                    };
                    if (debug) {
                        span.style.backgroundColor = '#aaa'
                    } else {
                        document.body.removeChild(div)
                    }
                    return coordinates
                }
                if (typeof module != "undefined" && typeof module.exports != "undefined") {
                    module.exports = getCaretCoordinates
                } else {
                    window.getCaretCoordinates = getCaretCoordinates
                }
            }())
        }
    ])
});
POWERMODE.colorful = true;  // make power mode colorful
POWERMODE.shake = false;    // turn off shake
document.body.addEventListener('input', POWERMODE);

引用

此脚本相较原始有些许改进。

转载自 林叶展弟弟 - 评论输入框打字特效
原始来源 QQ爹の博客 - 分享一个输入框的打字特效

搬瓦工VPS优惠套餐又又又补货啦,建站稳如狗,支持支付宝,循环出账94折优惠码BWH1ZBPVK
①年付仅需$18电信联通直连的亚洲优化线路,1核/512M内存/10G硬盘/1000GB@1Gbps【点击购买
②年付$18的可换成CN2线路(流量会变为180G),1核/512M内存/10G硬盘/500GB@1Gbps【点击购买
③年付$28的电信CN2联通直连线路,1核/512M内存/10G硬盘/500GB@1Gbps【点击购买】(购买后请到后台切DC8机房以获得最佳体验)

我的文章对您有帮助吗?
我很可爱 请给我钱
扫一扫拿红包 → 扫商家收款码 → 转账与红包相等的金额
即可免费赞赏,又可拿支付宝奖励金!
现在支付宝超抠门的,红包只给一两分钱了
Last modification:January 7th, 2018 at 09:29 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

31 comments

  1. 咸鱼  Windows 7 x64 Edition(Windows 7 x64 Edition) / Maxthon 5.1.5.2000(Maxthon 5.1.5.2000)

    用的是源码丢油猴然后// @include http:// 然后就美滋滋了
    就是会有卡顿不知道为啥. 用 JavaScript 脚本已经经过混淆压缩的会防止这个问题出现么?

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 67.0.3396.99(Google Chrome 67.0.3396.99)
      @咸鱼

      你可以试一下

  2. Tatsumi  Windows 10(Windows 10) / Opera 53.0.2907.99(Opera 53.0.2907.99)

    哇!好厉害的样子!

  3. 日常  Windows 10 x64 Edition(Windows 10 x64 Edition) / Firefox 60.0(Firefox 60.0)

    大佬大佬..能否同意下QQ呢...有很多关于主题 网页的问题想请教下|´・ω・)ノ

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.181(Google Chrome 66.0.3359.181)
      @日常

  4. 图安  Windows 7 x64 Edition(Windows 7 x64 Edition) / Firefox 58.0(Firefox 58.0)

    emmm 大佬 如果想把它添加到百度搜索里面要怎么做呢?是不是添加后下次再打开网页或者浏览器效果还在呢?

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
      @图安

      emmm这个是给自己的站用的……要是想应用到其他网站的话就通过油猴(Tampermonkey)吧

  5. nimenhao  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 62.0.3202.75(Google Chrome 62.0.3202.75)

    好厉害的dadiao

  6. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)

    大佬,我加了个评论框插件,但是显示不出来?怎么办?插件叫tocommer的

    1. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)
      @鸡腿堡

      又来麻烦你了想加你这样的评论特效

    2. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
      @鸡腿堡

      没用过不知道

      1. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)
        @神代綺凜

        那你这样的评论框和特效是怎么弄得能不能麻烦求插件

        1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
          @鸡腿堡

          特效就是我这片文章写的,怎么么弄都写得很清楚了,评论框是主题自己的我没改过

          1. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)
            @神代綺凜

            好的蟹蟹

            1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
              @鸡腿堡

              大佬 我把这个js上传到了网站目录 然后再baby后面引入了 为什么没效果显示呢?是不是因为我引入的路径不对呢?


              1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                @鸡腿堡

                f12看看console呀,看有没有资源404,有没有js错误

                1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
                  @神代綺凜

                  404 (Not Found) 它说我的路径下 找不到js? 我明放对了地方了...

                  1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                    @鸡腿堡

                    所以是路径写错了嘛,你难道是直接写主机上的路径么,绝对路径的话就直接写url,相对路径就写相对站点根目录的路径

                    1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
                      @神代綺凜

                      p u b lic_ht ml/ usr / themes/ commentTyping.js 我直接这样写了主机的路径
                      路径不是这样的么

                      1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                        @鸡腿堡

                        请自行百度html路径写法并深入研究

                        1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
                          @神代綺凜

                          大佬我刚刚研究了一下 好难懂啊
                          以前只用过图片引用 这个js引用好难懂啊
                          我想问下我把js放在服务器的p u b lic_ht ml目录里面 我要怎么引用啊

                          1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                            @鸡腿堡

                            一样的啊,为什么图片你会了这个就不会啊……

                            1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
                              @神代綺凜

                              挖槽 感谢大佬点醒啊 我终于引用成功了 我是参照了f12里面其他js的引用路径 最好成功了 哈哈哈

                              1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                                @鸡腿堡

                                ……所以实际上你之前还是不会的嘛

                                1. 鸡腿堡  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 57.0.2987.98(Google Chrome 57.0.2987.98)
                                  @神代綺凜

                                  那我现在领悟更深了 哈哈

                                  1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                                    @鸡腿堡

                                    那就好

                                    1. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)
                                      @神代綺凜

                                      大佬,我看到其他人的博客空白界面点击会出现蚊子特效,这个也是js实现的吗?

                                      1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
                                        @鸡腿堡

                                        是,而且typecho的话有人做成插件了。
                                        你想抄js的话F12搜搜点击出现的字就能搜到那块js了

                                        1. 鸡腿堡  Android 6.0(Android 6.0) / QQbrowser(QQbrowser)
                                          @神代綺凜

                                          好的我试试能不能抄到我的博客上。

  7. 柒月君  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 58.0.3029.61(Google Chrome 58.0.3029.61)
    怎么适配得md
    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 63.0.3239.132(Google Chrome 63.0.3239.132)
      @柒月君

      评论md?Typecho本身就有对评论开启md的功能