问题的产生
在写js的过程中,为了调试我们常常会写很多 console.log、console.info、console.group、console.warn、console.error代码来查看js的运行情况,但发布时又因为ie不支持console,又要去掉这些代码,一不小心就会出错。
本文分享自己昨晚写的一个console类来试图解决这一问题。当然,更好的做法是把测试代码分开写,那样就不会有这个问题。
解决思路
如何解决ie下不兼容的问题呢,那就是我们自己定义一个console类来覆盖浏览器提供的console功能,这样只要在页面中引用此js文件就可以了。
另外,此类还提供了查看输出的调试信息功能,console 定义了哪些功能呢,我们可以在这里看到:http://getfirebug.com/wiki/index.php/console_api,我们可以看到这里提供了很多方法,我们常用的有 console.log、console.info、console.group、console.warn、console.error、console.profile、console.time,最后两个是分析代码性能的,比较复杂,本文没有实现。
代码解析
第一步,当然是搭一个结构,覆盖浏览器(firebug、chrome)提供的console功能,这样直接引用此js文件即可保证浏览器(主要是ie)中不出错:
复制代码 代码如下:
console
var console={
assert:function(){
},
clear:function(){
},
count:function(){
},
debug:function(){
},
dir:function(){
},
dirxml:function(){
},
error:function(){
},
exception:function(){
},
group:function(name){
},
groupcollapsed:function(){
},
groupend:function(){
},
info:function(){
},
log:function(){
},
memoryprofile:function(){
},
memoryprofileend:function(){
},
profile:function(){
},
profileend:function(){
},
table:function(){
},
time:function(){
},
timeend:function(){
},
timestamp:function(){
},
trace:function(){
},
warn:function(){
}
};
第二步,实现 console.log方法。在所实现的几个方法中这个是最复杂的。
从firebug的api中我们可以看到,console.log不仅仅可以输出信息,还提供了类似 string.format的功能,直接引用原文如下:
here is the complete set of patterns that you may use for string substitution:
patterntype
%s string
%d, %i integer (numeric formatting is not yet supported)
%f floating point number (numeric formatting is not yet supported)
%o object hyperlink
%c style formatting
其中的%c比较特殊,是给输出添加样式的,比如我们在firebug中这样写:
复制代码 代码如下:
console.log('%ctest output', 'color:white; background-color:blue');
运行后的结果是这样的:
这里%c也可以跟 %s、%d等混用。
所以,在代码中我直接用replace进行替换,由于js中的replace默认只替换第一个匹配项,这里刚好,代码如下:
复制代码 代码如下:
var args=array.prototype.slice.call(arguments);
if(args.length>1){
var i=1,hasstyle=false;
if(args[0].indexof(%c)==0){
args[0]=args[0].replace(/%c/,);
i=2;
hasstyle=true;
}
for(;iif(/%s|%d|%i|%o/.test(args[0])){
args[0]=args[0].replace(/%s|%d|%i|%o/,args[i]);
}
else{
break;
}
}
if(iargs[0]=args[0]+ +args.slice(i).join( );
}
if(hasstyle){
consolehelper.showlog(args[0],args[1]);
}
else{
consolehelper.showlog(args[0]);
}
}
else if(args.length==1){
if(arguments[0] instanceof array){
consolehelper.showlog([+args[0]+]);
}
else if(arguments[0] instanceof function){
consolehelper.showlog(args[0],null,console_log_function);
}
else{
consolehelper.showlog(args[0]);
}
}
else{
consolehelper.showlog();
}
由于console.log可以接受多个参数,且个数不确定,所以这里直接没有写形参。对于%c虽然firebug中写在中间也是有效的,这里为了简单直接只对写在开头的有效。代码中先把参数转换为数组,然后对数组进行分情况处理。
当参数个数大于1时,对后面的参数用replace进行替换,然后把剩下的参数连接(join)起来进行输出。
当参数个数为1时,还要分两种情况,一是数组,二是方法。对于数组,按firebug中的格式,在两端加中括号,对于函数,把字的颜色变为绿色
当参数个数为0时,直接输出空字符串
后面的consolehelper.showlog是为了输出方便另外写的一个方法,在这个方法中把各种调试信息的结果显示在页面上的一个div(如果存在)中。
其他几个方法的思路跟这个差不多,只是样式不同,功能比这个简单,直接把参数连接起来输出即可。
整个console类代码如下:
复制代码 代码如下:
console全部代码
var console={
assert:function(){
},
clear:function(){
},
count:function(){
},
debug:function(){
},
dir:function(){
},
dirxml:function(){
},
error:function(){
var args=array.prototype.slice.call(arguments);
consolehelper.showerror(args.join( ));
},
exception:function(){
},
group:function(name){
consolehelper.showgroup(name);
},
groupcollapsed:function(){
},
groupend:function(){
},
info:function(){
var args=array.prototype.slice.call(arguments);
if(args.length==1){
if(arguments[0] instanceof array){
consolehelper.showinfo([+args[0]+]);
}
else if(arguments[0] instanceof function){
consolehelper.showinfo(args[0],console_log_function);
}
else{
consolehelper.showinfo(args[0]);
}
}
else{
consolehelper.showinfo(args.join( ));
}
},
log:function(){
var args=array.prototype.slice.call(arguments);
if(args.length>1){
var i=1,hasstyle=false;
if(args[0].indexof(%c)==0){
args[0]=args[0].replace(/%c/,);
i=2;
hasstyle=true;
}
for(;iif(/%s|%d|%i|%o/.test(args[0])){
args[0]=args[0].replace(/%s|%d|%i|%o/,args[i]);
}
else{
break;
}
}
if(iargs[0]=args[0]+ +args.slice(i).join( );
}
if(hasstyle){
consolehelper.showlog(args[0],args[1]);
}
else{
consolehelper.showlog(args[0]);
}
}
else if(args.length==1){
if(arguments[0] instanceof array){
consolehelper.showlog([+args[0]+]);
}
else if(arguments[0] instanceof function){
consolehelper.showlog(args[0],null,console_log_function);
}
else{
consolehelper.showlog(args[0]);
}
}
else{
consolehelper.showlog();
}
},
memoryprofile:function(){
},
memoryprofileend:function(){
},
profile:function(){
},
profileend:function(){
},
table:function(){
},
time:function(){
},
timeend:function(){
},
timestamp:function(){
},
trace:function(){
},
warn:function(){
var args=array.prototype.slice.call(arguments);
if(args.length==1){
if(arguments[0] instanceof array){
consolehelper.showwarn([+args[0]+]);
}
else if(arguments[0] instanceof function){
consolehelper.showwarn(args[0],console_log_function);
}
else{
consolehelper.showwarn(args[0]);
}
}
else{
consolehelper.showwarn(args.join( ));
}
}
};
consolehelper代码如下:
复制代码 代码如下:
var consolehelper={
showlog:function(val,style,cla){
if(cla){
cla=console_log +cla;
}
else{
cla=console_log;
}
this.show(val,style,cla);
},
showinfo:function(val,cla){
if(cla){
cla=console_info +cla;
}
else{
cla=console_info;
}
this.show(val,null,cla);
},
showwarn:function(val,cla){
if(cla){
cla=console_warn +cla;
}
else{
cla=console_warn;
}
this.show(val,null,cla);
},
showerror:function(val){
this.show(val,null,console_error);
},
showgroup:function(val){
if(!val){
val=;
}
this.show(val+:,null,console_group);
},
show:function(val,style,cla){
if(document.getelementbyid(showconsole)){
var div=document.createelement(div);
if(div.setattribute){
if(style){
div.setattribute(style,style);
}
}
else{
if(style){
div=document.createelement();
}
}
if(cla){
div.classname=cla;
}
var otext=document.createtextnode(val);
div.appendchild(otext);
document.getelementbyid(showconsole).appendchild(div);
}
}
};
注:如果想在页面中看到调试信息,直接在页面上添加一个id 为 showconsole 的隐藏的div即可。
样式(尽量跟firebug保持一致):
复制代码 代码如下:
.console_log{
border:1px solid #ccc;
color:#333;
padding:0px 5px;
min-height:24px;
line-height:24px;
margin-bottom:-1px;
}
.console_info{
border:1px solid #ccc;
color:#333;
padding:0px 5px;
min-height:24px;
line-height:24px;
margin-bottom:-1px;
background: url(data:image/png;base64,ivborw0kggoaaaansuheugaaabyaaaawcayaaadetgw7aaaeekleqvq4jbwuw0wczrth/998szo7o8bywa7wmbvke1epjuct1hzsk1pcqsfl6mufaujdtqyptyhy2kbgmchp+mbsfdbtnfjdarwvwlajsqxpkygysijpkvso2y3szxznz2apdynkl23vl05ykvno5tdn/ufmmclco7ier0ifip5xgru2ls8ai9cruquammycoyrjwvb6t/jf6tjdphbubkkxnrvh3zunlu9w1+q48koaaphwxfw1prunzoz1czvwtpx3t/0v8mhd3ezl7356l++zn05sbd5nkylq4laxklivj2patcpcw1exotirhye+pxzg9zc/px3i3qxqhhq9f37bmfm/hyva+cgrf7c+hzkxgmqi7g4idh5zgbpllduvhvwfndn/cf6u7bvh2/a+9oco5cqwfxl9oe937gxijxkcjxdy/hc8qo1j1v3a8hx4qryasbgb5pdtgbq8tjrvs9e0mf7evdbavmxo2c+xsvqt1vuawnzgcdmasmkyw4srgpv6mer1ynliksiaenyahwrwlqc6romxsvqtgxr2s1lsln1b3iy9v3ttockrnig7euawas4ae0exzlhrgl5li0jhigeatglgaapzogye3zuwfvnuazcuaszr2emo3wzoatkbuwwrsolao9ubv5+18r745jk+xtllhwjwjkms4cjfde1u9msbmdptkr1omals67y7ltzvmujzcuaa7hccod2elclwazwdesssfno+twbaycumm5t58ewp1ocsflcbumcx1iwlgxlgxweoayawv0fqchbvt1bcjnhfbweciduqtdfomztehw+pglywdmbelmabi4vyr/tzgrs3qwqi63vxlb1jgwxgiicbiyi+o3cjuch/jat8e+xckhz87cv+kzqxb22dxbqskdaqcnxbihah4xb4zs9xygiewpzfivrwtd8eo5fm0hgazna397596ppjm/aciylfgh1vgi0dq37chd91qxo5ctk2qdeb4t+bmt+uqr92+qoz3e296sze1dw1dnhq4xmibbyhfze+iorunm0aldwp21cukyi/3wul1wum5wimcpw4gcctx4+evhqq/ubb0/h3d76zmdch/zar9j5tois6eexjk7bimhxhnhsaea8hos9nrc2a9weubj6cgjg16ff4surzymgiojs7+ft0tbijrkrkmimzpimluikbedni5iogu7uoblecafjkwgcjpxgmh0ommv0qbf0qhkqksulfuziej0fv6ogwrv3xoaoqdmngpmkkrlrqhibi2v0etps+bvb/ts0kwabjioaueawisdbnuzamg6mqyqlr6iol6ovry8pdw5ibm2ohuiipqopeiseawg63kyzlclvdvfpass3nzwhtbc2c/a18nmddjnogeaaaaabjru5erkjggg==) no-repeat scroll 0 1px #ebf5ff;
padding-left:30px;
}
.console_warn{
border:1px solid #ccc;
color:#333;
padding:0px 5px;
min-height:24px;
line-height:24px;
margin-bottom:-1px;
background: url(data:image/png;base64,ivborw0kggoaaaansuheugaaabyaaaawcayaaadetgw7aaad/eleqvq4jbwux2gcvrshv3tndmattbjjsjnwaxvncuvjfbewlb4u9aeyjryurhwqkiivgqx0ozei+ciqcbyujvhe8aw0xafxsqhpsavqetwpddhtbwvs/nvz2dm5c+/xiumtdln86oudw71zvnvu7xx+sks4huvffirg3/lk/lcw9tp2l9lbe8ujzrbbawk/it+8ui+ospmhxpxkbpwu1pncjnztsxh6fm2xddawd3iqow/d3i5ygyxegpnthhpqmiiq/xpw/djfvv8huy86dttn7pf6ftem4p7nulkmcaso7yeiklqqeblyget8v66witmsd75zwpe/ibce2+hou+vz2ult3lmx2pyeknab5ly9gy50yzpdx99/wf1dnygfo3cr+8srcj3j6/6+hsnrwdebz0+/rbi4+yjv/rud3p34yutyhhg2rmhtlyqcrf4gbi8iwip89ij667mkc7yxfdp597pgd+bdhwku7an6dhg2v8nli7slweqgdjujq6gyce9hhmuq4ebn2kc32rq7f31wjnspbtx5dqpnfbi1iw4noaztbvnfzvvyztfbats2ytd9vddy+e36unluhg96n6ojwdzu4pwkrcams5etnakiu1uptbvsktpsczi4ayx4px5b01jfn6/lpzpw0gyefq+cqyds0hqh2m9btxarunrdcfykykvgwkzwmg1adwga5sppcl3vs2ozoh5a6wznqddigbmtmjvrt2cj1hkiomiqpjdhublqxjw/f2nr3umgjxcbhqmknmsef6oblkk+swvx9nragbccaryoolzfydpqn9egtbvydq9yaykrmfh8yz/onfas88eyhdq7fmtzz2o9cvdwtjxne74bczbs3fg0tzolapi5cgc5onsexmwtfbtevdpvu4bs6xmcfcbbjd5xypsb7h1vce4k1/dfpgwlwszxxltxnm/wvuigd/p7bj4xeycevurffbliezvvqsnfzo8nufw/ibmztroejzguv52nfq1efpd7oexvn+1avomjvyaf1hjp/hcurq4ebdptutx4wdjoieayxcty2jaumm5dsld4cobizbqva5vtf/5edz/2ko9lb3pnpowftc6bgzbfmhpntai+nsmvvgxeopawsqughhobg2noamibnjz0k5vkkkzpyk0nnhm5eck9cqdqf/5e3d/rplpqruo//epofx1wlljbkkwm1tpordmgcnjcozcwsivz6nah6xtjiooylmuutvalyep4gh+qbounyvbx5y4pwak+ukoajyjorls1vmdzpui4vleurs/fymiigh0dpvwuq9nzwrxhmumskib8pi9hgnlv1su9pt2ye/dubgyggid/avnzapv23zd/aaaaaelftksuqmcc) no-repeat scroll 0 1px #ffffc8;
padding-left:30px;
}
.console_error{
border:1px solid #ccc;
color:#ff0000;
padding:0px 5px;
min-height:24px;
line-height:24px;
margin-bottom:-1px;
background: url(data:image/png;base64,ivborw0kggoaaaansuheugaaabyaaaawcayaaadetgw7aaaabhncsvqicagifahkiaaaaalwsflzaaacyqaaamebwtbv+gaaabl0rvh0u29mdhdhcmuad3d3lmlua3njyxbllm9yz5vupboaaaqhsurbvdintzvtbxrvfmd/596zns1l210otmb2t62gmka2gvltc5ugagi0eg2jfgy+adawwq0fgkjge33zqcqf5efqcioj0rotxprathjy0hya2i6d7xz2u7tzfbhttlgkiyn/5m5n7j33n+fmofemggp4p2q9yycxslouxbaiockiyviw1r9/5n152jlzyeorkowz6a5vvdwsa2uxamoaonb/hpzoch4yoahe922achsxjv9m8l2qbetbp/smanoqtv1yz20bgejd5ichf+c23owzfmbhb4iz82hvw4epfcet66r8nu9ckdv9dinbnsefm6ns46ysbck4ozmf0gpz+xaz3369zgk6tfbm8ngcsy2+qixpvp8mnr/wmf+zlqnecnlwfvodg/gpf991i3pkjtv0hxdiisnbcfivyzztoxov1qmlhpfao9xhg1a8fm+hjorrptnyzbfe2ttrl71c8q9r+kkujpvi5ubfenqm4xgvm7/6gncyswfdntowbxp5+yv9y8dgtj+26hvw3wnktr6icgybib1pr2/fwaoh68zcukumvm7me58jwqmch+dwrrsmxaxyhb1woh4dj+pq6iucauiuaccmd+ki944dlyuv6zyktfnvsmvwsfmll0hryqk7jph/7recubkobrwvzwmto1tgvo4tj7bftmafngbbynwkevfsgrkfavgu7ik8qxt8vwgahjs7mlv0mxwxkh46db6pai2xvay4wrwglhm0+rz5svektaovclerqcq908/dqog6t3vm4ytc7x4+tg7gahxrdzjzwuw2g8lmaue5gujjyyydfkvafory+g6qcmnlyd94aivckfxiqgwmmynalzsizyeojkhfsascznfafy2uyny6hx5znw3he0uelqiup4eevqr+pev5ttuoquqwwjnfqrdvmhyabbuxbdkpnna+d2nopbey/qfd3d18qaspd39cso0dzianemsguziu2p2w5obdf6pld5q0z9oz8ny71pv8voik2o+qpxcgejzw94h3dy/udxta1ss4ktcidnz839/8wb2ly3dh20gwsobgdxzpm89+j9mfzlfrg6uifiu7cj7ho50a+j6hd30ifqwiwink9zv4s3vfg9y9g4hqyqzm8naup2zbnuyuxqa8uugx7z8zeh979x68oshk0i7bccvgbqrhk61cvpxfbp5o27uxoalnjejjnodh8gwcsbj5v/iamo+muzzfyhuikgvay71edfp0qcmta5stbw3lbuefrmnezbqn608t+fer+k6plv18cqpftcsar15zeoejddtxap5hjhtvfhfy/jm2v/ydlgj8wif6uf5+iyyorpigpymih9f3/xd1aeeecf6v+gflyzxwkd5f2qaaaabjru5erkjggg==) no-repeat scroll 0 1px #ffebeb;
padding-left:30px;
}
.console_group{
margin-top:20px;
font-size:16px;
font-weight:bolder;
}
.console_log_function{
color:green;
}
这里为了演示方便,三个小图标直接用的是base64格式的图片,就是上面代码中的三个长字符串,大家用时可以换成图片地址。
完整代码:
复制代码 代码如下:
jscode
login
result
javascript
html
css
all
edit
share
download
自定义console
自定义console(artwl.cnblogs.com)
小结
写这个js一方面是工作中有这方面的需求,另外也是因为在博问中看到有人问 javascript中如何获得console.log的值? ,前段时间有个国外学编程网站可以把console.log的结果直接显示在页面上,不知道是不是用了本文类似的方案。
欢迎大家留言讨论。
作者:artwl