將控制台信息顯示在前台頁面的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-width: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()

銷毀插件並恢復原來的控制台顯示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM