将控制台信息显示在前台页面的js插件

在拿出插件之前,先回顾一下apply()的用法,这里和call()做比较。

JavaScript中的每一个Function对象都有一个apply()方法和一个call()方法,它们的语法分别为:

/*apply()方法*/
function.apply(thisObj[, argArray])

/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

它们各自的定义:

apply:应用某一对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。

call:调用一个对象的一个方法,以另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。

它们的共同之处:

都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。

它们的不同之处:

apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。并且apply具有打散参数的作用。

call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。 

实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。

 以上只为更好的理解代码,下面看代码:

<script>
//插件
(function () {
    /*
     * logEl 输出的容器element
     * isInitialized 是否初始化
     * _console 
     */
    var logEl,
        isInitialized = false,
        _console = {};
    
    /*
     * 创建元素
     * tag 标签名称
     * css 样式
     */
    function createElement( tag, css ) {
        var element = document.createElement( tag );
        element.style.cssText = css;
        return element;
    }
    
    /*
     * 生成面板
     * options 自定义样式对象
     */
    function createPanel(options) {
        options.bgColor = options.bgColor || 'black';
        options.color = options.color || 'lightgreen';
        options.css = options.css || '';
        var div = createElement( 'div', 'font-family:Helvetica,Arial,sans-serif;font-size:10px;font-weight:bold;padding:5px;text-align:left;opacity:0.8;position:fixed;right:0;top:0;min-200px;max-height:50vh;overflow:auto;background:' + options.bgColor + ';color:' + options.color + ';' + options.css);
        return div;
    }

    /*
     * 日志信息,自定义log方法
     */
    function log() {
        var el = createElement( 'div', 'line-height:18px;background:' + (logEl.children.length % 2 ? 'rgba(255,255,255,0.2)' : '')); // zebra lines
        var val = [].slice.call(arguments).reduce(function(prev, arg) {//
            return prev + ' ' + arg;
        }, '');
        el.textContent = val;

        logEl.appendChild(el);
        // Scroll to last element
        logEl.scrollTop = logEl.scrollHeight - logEl.clientHeight;
    }

    /*
     * 清空控制台
     */
    function clear() {
        logEl.innerHTML = '';
    }

    /*
     * 初始化插件,可以添加附加选项
     */
    function init(options){
        if (isInitialized) { return; }

        isInitialized = true;
        options = options || {};
        logEl = createPanel(options);
        document.body.appendChild(logEl);
        
        if (!options.freeConsole) {
            // 同步打印更新
            _console.log = console.log;
            _console.clear = console.clear;
            
            console.log = originalFnCallDecorator(log, 'log');
            console.clear = originalFnCallDecorator(clear, 'clear');
        }
    }
    
    /*
     * 销毁插件并恢复原来的控制台显示
     */
    function destroy() {
        isInitialized = false;
        console.log = _console.log;
        console.clear = _console.clear;
        logEl.remove();
    }

    /*
     * 验证初始化 
     */
    function checkInitialized(){
        if (!isInitialized){
            throw 'You need to call `screenLog.init()` first.';
        }
    }

    function checkInitDecorator(fn){
        return function(){
            checkInitialized();
            return fn.apply(this, arguments);
        };
    }

    /*
     * 包含前台打印和后台打印
     */
    function originalFnCallDecorator(fn, fnName) {
        return function(){
            //前台打印
            fn.apply(this, arguments);
            if (typeof _console[fnName] === 'function') {
                //后台打印
                _console[fnName].apply(console, arguments);
            }
        };
    }

    window.screenLog = {
        init: init,
        log: originalFnCallDecorator(checkInitDecorator(log), 'log'),
        clear: originalFnCallDecorator(checkInitDecorator(clear), 'clear'),
        destroy: checkInitDecorator(destroy)
    };
})();


</script>
<script>
    screenLog.init();
    screenLog.log('String: Hello world');
    screenLog.log(21, 'multiple arguments');
    screenLog.log('Arrays', [1, 2, 3]);
    console.log('console.log also gets logged.');
    
        var i = 20;
    function log() {
        console.log('console log', Date.now());
        if (--i) { setTimeout(log, 1000); }
    }
    log();
</script>  

 使用方法:

1.初始化插件

在页面中引入screenlog.js文件。然后通过下面的方法来初始化该插件。

screenLog.init([option]); 

初始化方法有一个附加选项option:

color:可自定义文本颜色

bgColor:可自定义背景颜色

freeConsole:默认情况下console.log会被在屏幕上重写。你可以通过设置freeConsole为true,并使用screenLog.log() api来避免这种情况的发生。默认为false

2.screenLog.log(obj1[,obj2,obj2...,objn])

在屏幕上显示的log信息。

obj1...objn:要被输出的一组JavaScript对象或字符串。

3.screenLog.clear()

清空屏幕上的log信息。

4.screenLog.destory()

销毁插件并恢复原来的控制台显示。

原文地址:https://www.cnblogs.com/yinn/p/8309893.html