jsonFormater之应用
html代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/json_format.js" ></script> <script type="text/javascript" src="js/jsonFormater.js" ></script> <style> .jf-PropertyName{ color: #CC0000; } .jf-String{ color: #007777; } #josn_div{ font-family: Lucida Console,Georgia; color: #000000; border: solid 1px #CECECE; width: 90%; background-color: #FFFFDD; } </style> <script type="text/javascript"> var jf = null; //创建对象 $(function(){ var options = { dom : '#test_light', //对应容器的css选择器 baseDom : "json_text" }; jf = new JsonFormater(options); //创建对象 }); function testJson(){ jf.baseFomat($("#json_input").val()); } function testHighLight(){ jf.doFormat($("#json_input").val()); //格式化json } </script> </head> <body> <input type="text" id="json_input" placeholder="请输入json"/> <input type="button" value="数据转换" onclick="testJson()"/> <input type="button" value="高亮" onclick="testHighLight()"/> <br> <textarea id="json_text" cols="50" rows="20" style="background-color: #263238; font-weight:bold ; color: #A5E88D; font-family: "Source Sans Pro", 'Microsoft Yahei', '微软雅黑', sans-serif, Helvetica, 'Hiragino Sans GB', Arial;"> </textarea> <div id="josn_div"> <pre id="test_light"> </pre> </div> </body> </html>
JS脚本:
function JsonFormater(opt) { this.options = $.extend({ dom: '',//带有高亮、关键字颜色设置 baseDom:'', //基本格式节点 tabSize: 2, singleTab: " ", quoteKeys: true, imgCollapsed: "img/Collapsed.gif", imgExpanded: "img/Expanded.gif", isCollapsible: true }, opt || {}); this.isFormated = false; this.obj = { _dateObj: new Date(), _regexpObj: new RegExp() }; this.init(); } JsonFormater.prototype = { init: function () { this.tab = this.multiplyString(this.options.tabSize, this.options.singleTab); this.bindEvent(); }, // 基本格式转换-只读模式 baseFomat: function(txt,compress/*是否为压缩模式*/){/* 格式化JSON源码(对象转换为JSON文本) */ var indentChar = ' '; if(/^\s*$/.test(txt)){ alert('数据为空,无法格式化! '); return; } try{var data=eval('('+txt+')');} catch(e){ alert('数据源语法错误,格式化失败! 错误信息: '+e.description,'err'); return; }; var draw=[],last=false,This=this,line=compress?'':'\n',nodeCount=0,maxDepth=0; var notify=function(name,value,isLast,indent/*缩进*/,formObj){ nodeCount++;/*节点计数*/ for (var i=0,tab='';i<indent;i++ )tab+=indentChar;/* 缩进HTML */ tab=compress?'':tab;/*压缩模式忽略缩进*/ maxDepth=++indent;/*缩进递增并记录*/ if(value&&value.constructor==Array){/*处理数组*/ draw.push(tab+(formObj?('"'+name+'":'):'')+'['+line);/*缩进'[' 然后换行*/ for (var i=0;i<value.length;i++) notify(i,value[i],i==value.length-1,indent,false); draw.push(tab+']'+(isLast?line:(','+line)));/*缩进']'换行,若非尾元素则添加逗号*/ }else if(value&&typeof value=='object'){/*处理对象*/ draw.push(tab+(formObj?('"'+name+'":'):'')+'{'+line);/*缩进'{' 然后换行*/ var len=0,i=0; for(var key in value)len++; for(var key in value)notify(key,value[key],++i==len,indent,true); draw.push(tab+'}'+(isLast?line:(','+line)));/*缩进'}'换行,若非尾元素则添加逗号*/ }else{ if(typeof value=='string')value='"'+value+'"'; draw.push(tab+(formObj?('"'+name+'":'):'')+value+(isLast?'':',')+line); }; }; var isLast=true,indent=0; notify('',data,isLast,indent,false); if(this.options.baseDom){ $("#"+this.options.baseDom).html(draw.join('')); }else{ return draw.join(''); } }, // 带有颜色、高亮功能额格式化方法 doFormat: function (json) { var html; var obj; try { if(typeof json == 'object'){ obj = [json]; }else{ if (json == ""){ json = "\"\""; } obj = eval("[" + json + "]"); } html = this.ProcessObject(obj[0], 0, false, false, false); $(this.options.dom).html("<pre class='jf-CodeContainer'>" + html + "</pre>"); this.isFormated = true; } catch (e) { alert("JSON数据格式不正确:\n" + e.message); $(this.options.dom).html(""); this.isFormated = false; } }, bindEvent: function () { var that = this; $(this.options.dom).off('click','.imgToggle'); $(this.options.dom).on('click', '.imgToggle', function () { if (that.isFormated == false) { return; } that.makeContentVisible($(this).parent().next(), !$(this).data('status')); }); }, expandAll: function () { if (this.isFormated == false) { return; } var that = this; this.traverseChildren($(this.options.dom), function(element){ if(element.hasClass('jf-collapsible')){ that.makeContentVisible(element, true); } }, 0); }, collapseAll: function () { if (this.isFormated == false) { return; } var that = this; this.traverseChildren($(this.options.dom), function(element){ if(element.hasClass('jf-collapsible')){ that.makeContentVisible(element, false); } }, 0); }, collapseLevel: function(level){ if (this.isFormated == false) { return; } var that = this; this.traverseChildren($(this.options.dom), function(element, depth){ if(element.hasClass('jf-collapsible')){ if(depth >= level){ that.makeContentVisible(element, false); }else{ that.makeContentVisible(element, true); } } }, 0); }, isArray: function (obj) { return obj && typeof obj === 'object' && typeof obj.length === 'number' && !(obj.propertyIsEnumerable('length')); }, getRow: function (indent, data, isPropertyContent) { var tabs = ""; if (!isPropertyContent) { tabs = this.multiplyString(indent, this.tab); } if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n") { data = data + "\n"; } return tabs + data; }, formatLiteral: function (literal, quote, comma, indent, isArray, style) { if (typeof literal == 'string') { literal = literal.split("<").join("<").split(">").join(">"); } var str = "<span class='jf-" + style + "'>" + quote + literal + quote + comma + "</span>"; if (isArray) str = this.getRow(indent, str); return str; }, formatFunction: function (indent, obj) { var tabs; var i; var funcStrArray = obj.toString().split("\n"); var str = ""; tabs = this.multiplyString(indent, this.tab); for (i = 0; i < funcStrArray.length; i++) { str += ((i == 0) ? "" : tabs) + funcStrArray[i] + "\n"; } return str; }, multiplyString: function (num, str) { var result = ''; for (var i = 0; i < num; i++) { result += str; } return result; }, traverseChildren: function (element, func, depth) { var length = element.children().length; for (var i = 0; i < length; i++) { this.traverseChildren(element.children().eq(i), func, depth + 1); } func(element, depth); }, makeContentVisible : function(element, visible){ var img = element.prev().find('img'); if(visible){ element.show(); img.attr('src', this.options.imgExpanded); img.data('status', 1); }else{ element.hide(); img.attr('src', this.options.imgCollapsed); img.data('status', 0); } }, ProcessObject: function (obj, indent, addComma, isArray, isPropertyContent) { var html = ""; var comma = (addComma) ? "<span class='jf-Comma'>,</span> " : ""; var type = typeof obj; var clpsHtml = ""; var prop; if (this.isArray(obj)) { if (obj.length == 0) { html += this.getRow(indent, "<span class='jf-ArrayBrace'>[ ]</span>" + comma, isPropertyContent); } else { clpsHtml = this.options.isCollapsible ? "<span><img class='imgToggle' data-status='1' src='" + this.options.imgExpanded + "'/></span><span class='jf-collapsible'>" : ""; html += this.getRow(indent, "<span class='jf-ArrayBrace'>[</span>" + clpsHtml, isPropertyContent); for (var i = 0; i < obj.length; i++) { html += this.ProcessObject(obj[i], indent + 1, i < (obj.length - 1), true, false); } clpsHtml = this.options.isCollapsible ? "</span>" : ""; html += this.getRow(indent, clpsHtml + "<span class='jf-ArrayBrace'>]</span>" + comma); } } else if (type == 'object') { if (obj == null) { html += this.formatLiteral("null", "", comma, indent, isArray, "Null"); } else { var numProps = 0; for (prop in obj) numProps++; if (numProps == 0) { html += this.getRow(indent, "<span class='jf-ObjectBrace'>{ }</span>" + comma, isPropertyContent); } else { clpsHtml = this.options.isCollapsible ? "<span><img class='imgToggle' data-status='1' src='" + this.options.imgExpanded + "'/></span><span class='jf-collapsible'>" : ""; html += this.getRow(indent, "<span class='jf-ObjectBrace'>{</span>" + clpsHtml, isPropertyContent); var j = 0; for (prop in obj) { var quote = this.options.quoteKeys ? "\"" : ""; html += this.getRow(indent + 1, "<span class='jf-PropertyName'>" + quote + prop + quote + "</span>: " + this.ProcessObject(obj[prop], indent + 1, ++j < numProps, false, true)); } clpsHtml = this.options.isCollapsible ? "</span>" : ""; html += this.getRow(indent, clpsHtml + "<span class='jf-ObjectBrace'>}</span>" + comma); } } } else if (type == 'number') { html += this.formatLiteral(obj, "", comma, indent, isArray, "Number"); } else if (type == 'boolean') { html += this.formatLiteral(obj, "", comma, indent, isArray, "Boolean"); }else if (type == 'undefined') { html += this.formatLiteral("undefined", "", comma, indent, isArray, "Null"); } else { html += this.formatLiteral(obj.toString().split("\\").join("\\\\").split('"').join('\\"'), "\"", comma, indent, isArray, "String"); } return html; } };