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

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

  1. /*apply()方法*/
  2. function.apply(thisObj[, argArray])
  3.  
  4. /*call()方法*/
  5. 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的功能是一样的,只是传入的参数列表形式不同。

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

  1. <script>
  2. //插件
  3. (function () {
  4. /*
  5. * logEl 输出的容器element
  6. * isInitialized 是否初始化
  7. * _console
  8. */
  9. var logEl,
  10. isInitialized = false,
  11. _console = {};
  12.  
  13. /*
  14. * 创建元素
  15. * tag 标签名称
  16. * css 样式
  17. */
  18. function createElement( tag, css ) {
  19. var element = document.createElement( tag );
  20. element.style.cssText = css;
  21. return element;
  22. }
  23.  
  24. /*
  25. * 生成面板
  26. * options 自定义样式对象
  27. */
  28. function createPanel(options) {
  29. options.bgColor = options.bgColor || 'black';
  30. options.color = options.color || 'lightgreen';
  31. options.css = options.css || '';
  32. 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);
  33. return div;
  34. }
  35.  
  36. /*
  37. * 日志信息,自定义log方法
  38. */
  39. function log() {
  40. var el = createElement( 'div', 'line-height:18px;background:' + (logEl.children.length % 2 ? 'rgba(255,255,255,0.2)' : '')); // zebra lines
  41. var val = [].slice.call(arguments).reduce(function(prev, arg) {//
  42. return prev + ' ' + arg;
  43. }, '');
  44. el.textContent = val;
  45.  
  46. logEl.appendChild(el);
  47. // Scroll to last element
  48. logEl.scrollTop = logEl.scrollHeight - logEl.clientHeight;
  49. }
  50.  
  51. /*
  52. * 清空控制台
  53. */
  54. function clear() {
  55. logEl.innerHTML = '';
  56. }
  57.  
  58. /*
  59. * 初始化插件,可以添加附加选项
  60. */
  61. function init(options){
  62. if (isInitialized) { return; }
  63.  
  64. isInitialized = true;
  65. options = options || {};
  66. logEl = createPanel(options);
  67. document.body.appendChild(logEl);
  68.  
  69. if (!options.freeConsole) {
  70. // 同步打印更新
  71. _console.log = console.log;
  72. _console.clear = console.clear;
  73.  
  74. console.log = originalFnCallDecorator(log, 'log');
  75. console.clear = originalFnCallDecorator(clear, 'clear');
  76. }
  77. }
  78.  
  79. /*
  80. * 销毁插件并恢复原来的控制台显示
  81. */
  82. function destroy() {
  83. isInitialized = false;
  84. console.log = _console.log;
  85. console.clear = _console.clear;
  86. logEl.remove();
  87. }
  88.  
  89. /*
  90. * 验证初始化
  91. */
  92. function checkInitialized(){
  93. if (!isInitialized){
  94. throw 'You need to call `screenLog.init()` first.';
  95. }
  96. }
  97.  
  98. function checkInitDecorator(fn){
  99. return function(){
  100. checkInitialized();
  101. return fn.apply(this, arguments);
  102. };
  103. }
  104.  
  105. /*
  106. * 包含前台打印和后台打印
  107. */
  108. function originalFnCallDecorator(fn, fnName) {
  109. return function(){
  110. //前台打印
  111. fn.apply(this, arguments);
  112. if (typeof _console[fnName] === 'function') {
  113. //后台打印
  114. _console[fnName].apply(console, arguments);
  115. }
  116. };
  117. }
  118.  
  119. window.screenLog = {
  120. init: init,
  121. log: originalFnCallDecorator(checkInitDecorator(log), 'log'),
  122. clear: originalFnCallDecorator(checkInitDecorator(clear), 'clear'),
  123. destroy: checkInitDecorator(destroy)
  124. };
  125. })();
  126.  
  127. </script>
  1. <script>
  2. screenLog.init();
  3. screenLog.log('String: Hello world');
  4. screenLog.log(21, 'multiple arguments');
  5. screenLog.log('Arrays', [1, 2, 3]);
  6. console.log('console.log also gets logged.');
  7.  
  8. var i = 20;
  9. function log() {
  10. console.log('console log', Date.now());
  11. if (--i) { setTimeout(log, 1000); }
  12. }
  13. log();
  14. </script>

运行代码

 使用方法:

1.初始化插件

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

  1. 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()

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

将控制台信息显示在前台页面的js插件的更多相关文章

  1. javascript笔记——点击按钮(或超链接)如何跳转到另外一个页面并执行目标页面的js函数

    页面跳转同时执行js代码$(function(){});url参数传递 标题的前半部分其实不必赘述,按钮也可以换成超链接.. 假设是需要在A页面上的一个按钮,点击后跳转到B页面,传一些参数后且并B页面 ...

  2. thinkphp在前端页面的js代码中可以使用 U方法吗? 可以使用模板变量如__URL__等吗?

    thinkphp在前端页面的js代码中可以使用 U方法吗? : 可以的! tp的U方法, 是"全局的", 什么是全局的? 就是, 可以在 "任何地方"使用的: ...

  3. 域名ip自动跳转 跳转指定页面的js

    域名ip自动跳转 跳转指定页面的js 为了应对百度审核,需要客户的网站在个别地区跳转到另一个页面,就搞到了这段代码,屡试不爽,超实用.下面把地址换成你要访问的网站url地址或者文件url地址即可.超实 ...

  4. 关于前台jsp页面的js取值问题

    在后程序中传一个字符串到前台页面上,后台代码model.addAttribute("ccc", "cccc"); 在页面js上用下面两种方法取值 1. var ...

  5. 调用上一个页面的js方法

    点击商品分类,弹出下框 点击确定,将选中的类别的name和唯一的code返回到上个页面 function save(){ var ids = getIdSelections(); jp.get(&qu ...

  6. 引用公共页面的js函数报错

    对于网站来说很多页面之间都有着大量的共享模块,如页头,页脚和用户栏等.很多时候为了方便.省事,我们在公共模块写函数,然后在别的页面里调用.但我们在引用公共的js函数时,有些可以引用,有些却报错:这是因 ...

  7. 模式窗体中调用父页面js与非模式化调用非父页面的js方法

    最近项目中使用模式窗体,遇到以下问题记录一下: 模式窗体:你必须关闭该窗体,才能操作其它窗体:比如说,必须按确定或取消,或者按关闭. 非模式窗体:不必关闭该窗体,就可转换到其它窗体上进行操作. 一:非 ...

  8. hexo的next主题博客中加入分类页面的js,实现多级目录,并且能够点击展开,隐藏下级目录~(不知道算不算深度优化~~~)

    个人博客:https://mmmmmm.me 源码:https://github.com/dataiyangu/dataiyangu.github.io 多级标题 在自己的xxxx.md文件中做如下修 ...

  9. 使用内部Servlet转发JSP后页面的JS,CSS等资源引入问题的解决

    转载自:https://blog.csdn.net/weixin_44353336/article/details/90677792 问题原因 我们在进行web项目开发过程中,经常会在web页面引入一 ...

随机推荐

  1. activeMq 使用方法

    一:activeMq介绍 ActiveMQ是一种开源的,实现了JMS1.1规范的,面向消息(MOM)的中间件,为应用程序提供高效的.可扩展的.稳定的和安全的企业级消息通信,下载地址是:http://a ...

  2. 如何把git仓库(包含所有提交历史)迁移到gitlab

    在gitlab上new 一个project 跳转到本地的git 目录中,运行命令 git remote add gitlab gitlab_new_project_address -最后运行如下命令, ...

  3. Springboot-添加对jsp支持

    1,在项目的配置文件加入以下依赖 <dependency> <groupId>javax.servlet</groupId> <artifactId>j ...

  4. Flink升级到1.4版本遇到的坑

    Flink 1.4没出来以前,一直使用Flink 1.3.2,感觉还算稳定,最近将运行环境升级到1.4,遇到了一些坑: 1.需要将可运行程序,基于1.4.0重新编译一次 2.对比了一下flink-co ...

  5. 9.python面向对象编程

    面向对象的几个核心特性如下 Class 类一个类即是对一类拥有相同属性的对象的抽象.蓝图.原型.在类中定义了这些对象的都具备的属性(variables(data)).共同的方法 Object 对象 一 ...

  6. Android 开发,你遇上 Emoji 头疼吗?

    在 Android 中,如果需要使用的到 Emoji 表情,你会发现在某些设备上,有一些 Emoji 表情会被以豆腐块 "☐" 的形式显示,这是因为当前设备并不支持这个 Emoji ...

  7. Oracle初级——续续篇

    逝者如斯夫,不舍昼夜 所有的SQL都经过测试,可粘贴,可复制,有问题请各位大神指出...... --约束 与表一起使用 约束不合理的数据,使其不能进入表中? ','李小龙','一班','该学生成天练武 ...

  8. 单源最短路径(1):Dijkstra 算法

    一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...

  9. Java I/O---概述

    对于程序设计者来说,创建一个好的输入/输出系统(I/O)系统是一项艰难的任务. 现在大量不同方案已经说明了这一点.挑战似乎来自于要涵盖所有的可能性.不仅存在各种I/O源端和想要与之通信的接收端(文件. ...

  10. C语言位操作的算法

    1.头文件 #ifndef _INC_BITOPERATION #define _INC_BITOPERATION #endif /* 封装了所有的位操作运算 */ #include<stdio ...