开发背景
有些产品在开发中会涉及到客户端,而在客户端中开发调试中,一些调试工具不能发挥作用。特别是在遇上与JS相关问题之后,却不知道哪里出问题,调试手段也仅剩alert这种方式。并且因为无法查看控制台,console.log也不能使用,而alert也只能查看简单类型的数据,类似对象之类的便无法查看了。所以,遇上问题之后,常常会卡在那里,不知道该从何下手,通常一个小问题都会卡很久,但是最后发现错误的时候,获取只是因为多一个或者少一个符号。在缺乏一个有效的调试手段时,开发过程变艰难很多。所以便想要整理出一个JS组件,该组件能帮助捕获程序异常,并能有效打印复杂变量。当然,如果你有其他更有效的调试工具(手段),望不吝赐教,感激不尽。
修改日志
2016-01-21 –基本上重写该组件。提供更多的用法。
2016-01-22 –重写调试信息生成部分代码,能更加灵活方便的生成语句,且提供了更详细的参数显示。
2016-01-25 –新增多种格式输出,例如GE.log(data, ‘json’), GE.log(data, ‘html’)
2016-01-26 –剔除之前的jquery依赖,纯JS实现。并修复IE兼容问题。下载地址资源:http://download.csdn.net/detail/a7326012009/9418647
2016-01-27 –添加队列机制,新增翻页,便于调试,修复部分样式及功能错误
使用说明
组件介绍:目前版本的debug.js比较简陋,只提供两个功能,1、捕获异常 2、调试输出复杂变量。如果日后在工作中有新的需求,会进行及时更新。
使用方式:
1、于页面中引入debug.js即可如
< scritp id=”hq-jquery-client”
data-pop-width=”300” data-pop-height=”400” data-debug-switch=”on”
s rc=”jquery-client-debug.js”>
2、关于捕获异常功能:调试功能可以通过参数配置进行开关。通过在script引入的时候对data-debug-switch进行on/off。
3、关于输出变量:在需要输出的变量名称后使用GE.log即可,如GE.log(thsInfo)。
参数说明
data-pop-width : 调试窗口的宽度,默认200px;
data-pop-height : 调试窗口的高度,默认400px;
data-debug-switch : on/off 开启/关闭错误提示
data-wrap-sptor-num : 1 换行间距,默认一个换行距离
data-level-sptor-num : 2 行里间距,默认两个制表符距离
GE.log参数说明
GE.log(data, type);
—- data[必选],想要打印的变量
—- type[可选],选择欲输出的类型,目前可提供json,html形式输出
// @charset "utf-8";
/**
* 客户端调试用JS(jQuery版)
* author : yinggaozhen(yinggaozhen@myhexin.com)
* create : 2015-9-10
* version : 0.0.4
* @demo :
* <script type="text/javascript" id="hq-jquery-client" data-pop-width="300" data-pop-height="400" data-debug-switch="on" src="jquery-client-debug.js" ></script>
* var std = {name : 'jack'}
* GE.log(std);
*/
+function($, window) {
var JQUERY_TAG_ID = '#hq-jquery-client';
var RECUR_WRAP_SPTOR = '<br>';
var RECUR_LEVEL_SPTOR = ' ';
var OBJECT_SENTENCE = '';
var COMPLEX_RENDER_TEMPLATE = "__LEVELSP____KEY__ __ARROW__ __TYPE__(__SIZE__)__WRAPSP__";
var SINGLE_RENDER_TEMPLATE = "__LEVELSP____KEY__ __ARROW__ __VALUE__(__TYPE__)__WRAPSP__";
var DEFAULT_OPTIONS = {
popMask : 'off',
popWidth : 200,
popHeight : 400,
wrapSptorNum : 1,
levelSptorNum : 2,
debugOnlyClient : 'on'
}
if (typeof jQuery === 'undefined') {
throw new Error('No Detected Jquery Plz To Load It~');
return;
}
if (typeof GE !== 'undefined') {
throw new Error('The Variable `GE` is Already Exist!');
return;
}
GE = {};
GE.init = function(printType) {
this.isInit = true;
this.isShown = false;
this.isClient = false;
this.loadCssStatus = false;
this.printType = (printType || 'normal').toUpperCase();
this.options = $.extend({}, DEFAULT_OPTIONS, $(JQUERY_TAG_ID).data());
this.recurWrapSptor = this._repeatSptor(this.options.wrapSptorNum, RECUR_WRAP_SPTOR);
this.recurLevelSptor = this._repeatSptor(this.options.levelSptorNum, RECUR_LEVEL_SPTOR);
try {
external.createObject('Quote');
this.isClient = true;
} catch (e) {
}
}
GE.log = function(data, type) {
if (!this.isInit) this.init(type);
if (this.options.debugOnlyClient === 'off' || (this.options.debugOnlyClient === 'on' && this.isClient)) {
var rsivDta = null;
dataType = this._typeJudge(data);
switch (this.printType) {
case 'JSON' :
break;
case 'HTML' :
break;
default :
break;
}
rsivDta = rsivDta === null ? this._rsiv(data) : rsivDta;
this._pop(rsivDta);
} else {
console.log(data);
}
}
GE._rsiv = function (data, level) {
var me = this,
rsivTxt = '';
level = level ? parseInt(level) : 0;
var renderDta = {};
renderDta.type = me._typeJudge(data);
renderDta.wrapSp = me.recurWrapSptor;
renderDta.levelSp = me._repeatSptor(level, me.recurLevelSptor)
if ('Array' === renderDta.type || 'Object' === renderDta.type) {
for (var key in data) {
renderDta.type = me._typeJudge(data[key]);
renderDta.key = key;
if (data[key] && ('Array' === renderDta.type || 'Object' === renderDta.type)) {
renderDta.size = me._calObjectSize(data[key]);
rsivTxt += me._renderTemplate(renderDta, 'complex');
rsivTxt += me._rsiv(data[key], level + 1);
} else {
renderDta.value = data[key];
rsivTxt += me._renderTemplate(renderDta);
}
}
} else {
renderDta.key = '';
renderDta.value = data;
rsivTxt += me._renderTemplate(renderDta);
}
return rsivTxt;
}
GE._renderTemplate = function(renderDta, renderType) {
renderType = renderType || 'single';
var _renderTemplate = renderType == 'single' ? SINGLE_RENDER_TEMPLATE : COMPLEX_RENDER_TEMPLATE;
renderDta.arrow = renderDta.key ? '=>' : '';
for (var renderKey in renderDta) {
_renderTemplate = _renderTemplate.replace('__' + renderKey.toUpperCase() + '__', renderDta[renderKey]);
}
return '<pre>' + _renderTemplate + '</pre>';
}
GE._pop = function(rsivDta, width, height) {
width = parseFloat(width) || this.options.popWidth;
height = parseFloat(height) || this.options.popHeight;
this._loadStyle();
var builedPop = this._buildPop(rsivDta)
$('body').append(builedPop.popBody);
if (this.options.popMask == 'on') $('body').append(builedPop.popMask);
var $cPopBox = $("#c_pop_box"),
$cMask = $("#mark");
var adjustHeight = ($(window).height() - height) / 2;
$cPopBox.show().css({
'width' : width,
'height' : height,
'margin-left' : -(width / 2) + 'px',
'margin-top' : -(height / 2) + 'px',
'_top' : 'expression(eval(document.documentElement.scrollTop)+' + adjustHeight + ')'
})
$(window).scroll(function() {
if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
$cPopBox.css('_top', 'expression(eval(document.documentElement.scrollTop)+' + adjustHeight + ')');
$cPopBox.css('_position', 'absolute');
}
});
$cPopBox.on('click', '#c_hd_close', function() {
$cPopBox.remove();
$cMask.remove();
});
}
GE._loadStyle = function () {
if (!this.loadCssStatus) {
var cssFileLink = document.createElement('link'),
headDom = document.getElementsByTagName('head')[0];
cssFileLink.href = 'http://s.thsi.cn/css/test/debug.css';
cssFileLink.type = 'text/css';
cssFileLink.rel = 'stylesheet';
headDom.insertBefore(cssFileLink, headDom.firstChild);
GE.loadCssSta = true;
}
}
GE._buildPop = function(rsivDta) {
rsivDta = rsivDta || '无调试信息...';
return {
popBody : '<div class="c_pop" id="c_pop_box"><div class="pop_hd"><span class="hd_title" id="c_hd_title">调试信息</span><a href="###" class="hd_close" id="c_hd_close">x</a></div><div class="pop_content" id="c_pop_content">' + rsivDta +'</div></div>',
popMask : '<div class="mark" id="mark"></div>'
}
}
GE._typeJudge = function(value) {
return Object.prototype.toString.call(value).replace(/\[object \s |\]/g, '');
}
GE._repeatSptor = function(reNum, reVal) {
reNum = typeof reNum == 'number' ? reNum : (parseInt(reNum) || 1);
return new Array(reNum + 1).join(reVal);
}
GE._calObjectSize = function(d) {
return $.map(d || {}, function(o) {
if (typeof o != 'undefined') return 1;
}).length;
}
GE._htmlspecialchars = function(html) {
return html;
//发现IE6下读取文本错误=_=
return html.replace(/&/g, '&')
.replace(/"/g, '"').replace(/'/g, ''')
.replace(/</g, '<').replace(/>/g, '>')
.replace(/\n/g, '<br>').replace(/\t/g, ' ');
}
//The Function For Debug
var debugSwitch = $(JQUERY_TAG_ID).data().debugSwitch || 'on';
if ('on' === debugSwitch) {
window.onerror = function(errorMsg, errorUrl, errorLine) {
var errorInfo = [];
errorInfo.push('错误信息: ' + errorMsg + "\n");
errorInfo.push('错误页面: ' + errorUrl + "\n");
errorInfo.push('错误位置: ' + errorLine + "行\n");
alert(errorInfo.join(''));
return false;
}
}
}(jQuery, window)