JSON 编辑器实现代码

大家可以输入或者粘贴一些JSON数据来校验是否正确。
按Tab键自动全文缩进格式化。

 
JSON 编辑器
核心代码


代码如下:

<script type="text/javascript"><!--
/*
main Object
*/
JE={
data:{},/* 关联数据 */
code:false,/* 格式化后的代码 */
oldCode:[],/* 历史代码 */
editUI:null,/* 关联编辑框 */
msgUI:null,/* 信息显示窗口 */
treeUI:null,/* 树窗口 */
name:'JE',/* 实例名 */
root:'<b>JSON无忧</b>',/* 根节点标题 */
checkbox:0,/* 是否添加复框 */
hot:null,/* 选中节点 */
indent:' ',/*缩进符'\t'或者4个' '*/
firstUp:true,/*第一次自动刷新*/
onclick:Array,/*树点击通知*/
countInfo:'',/*统计信息*/
formating:false,/* 格式化中(禁止重构树) */
ico:{/* 树图标 */
//文件夹结构线
r0:'img?uuid=20166b3094daba4bc6e18817b8301b093a',
r0c:'img?uuid=208018827ed877e31810e838d33e4ac2b0',
r1:'img?uuid=2094c793496278bde84be80bb6cb2117f5',
r1c:'img?uuid=205f2329c537dcfd32b5f33bf642f76fa6',
r2:'img?uuid=20af62be7c197cae64d3e533f7aaf28c25',
r2c:'img?uuid=20a005983863e5bc8544cecd8b7f82fcdb',
//前缀图片
nl:'img?uuid=20f508bdc9bb8d98f4529e0fa2475b91bb',
vl:'img?uuid=20d5de63f4e6927bbb23c377bd1073d26f',
//文件结构线
f1:'img?uuid=202ccc639afd44130a3946e9837672479c',
f2:'img?uuid=20900ceb0053a2f7bd07a22337c4e4c72c',
root:'img?uuid=2069cf3fd1e53a2bb365f771eac65b50a2',
//文件夹
arr:'img?uuid=20b7d6e86f4f288ea097c10b1c0d7f4b6b',
arrc:'img?uuid=20b7d6e86f4f288ea097c10b1c0d7f4b6b',
obj:'img?uuid=20c34d1d5d5a4639061e08165c61a97e63',
objc:'img?uuid=20c34d1d5d5a4639061e08165c61a97e63',
//文件
arr2:'img?uuid=20327500502b71ed0278a0cc1bf8f8bb41',
obj2:'img?uuid=203346cafeedac1fb7628bc886b9b7fb47'
},
toTree:function(){/* JSON转换为树HTML,同时格式化代码 */
var draw=[],This=this,ico=this.ico;
JE.firstUp=false;/*完成首次自动构造*/
var notify=function(prefix/*前缀HTML*/,lastParent/*父是否是尾节点(确定图标是空白|结构线)*/,name /*节点名*/,value/*节点值*/,formObj/* 父是否是对象(确定子图标) */){/* 构造子节点 */
var rl=prefix==''?ico.r0:lastParent?ico.r1:ico.r2;/* 配置根节点图标 */
if(value&&value.constructor==Array){/* 处理数组节点 */
draw.push('<dl><dt>',This.draw(prefix,rl,ico.arr,name,''),'</dt><dd>');/* 绘制文件夹 */
for (var i=0;i<value.length;i++)
notify(prefix+This.img(lastParent?ico.nl:ico.vl),i==value.length-1,i,value[i]);
draw.push('</dd></dl>');
}else if(value&&typeof value=='object'){/* 处理对象节点 */
draw.push('<dl><dt>',This.draw(prefix,rl,ico.obj,name,''),'</dt><dd>');/* 绘制文件夹 */
var len=0,i=0;
for(var key in value)len++;/* 获取对象成员总数 */
for(var key in value)notify(prefix+This.img(lastParent?ico.nl:ico.vl),++i==len,key,value[key],true);
draw.push('</dd></dl>');
}else{/* 处理叶节点(绘制文件) */
draw.push('<dl><dt>',This.draw(prefix,lastParent?ico.f1:ico.f2,formObj?ico.obj2:ico.arr2,name,value),'</dt></dl>');
};
};/* 不是[]或者{}不绘制 */
if(typeof this.data=='object'){notify('',true,this.root,this.data);};
if(this.treeUI)this.treeUI.innerHTML=draw.join('');/* 显示在树窗口 */
this.msg('成功构造树视图!');
},
draw:function(prevfix,line,ico,name,value){/* 子项HTML构造器 */
var cmd=false,J=this.ico,imgName=false;
switch (line) {//传递切换图标
case J.r0:imgName='r0';break;
case J.r1:imgName='r1';break;
case J.r2:imgName='r2';
}
if(imgName)cmd=' onclick="'+this.name+'.show(this,\''+imgName+'\')" ';/* 加入折叠命令 */
var type=typeof name=='string'?'(对象成员)':'(数组索引)';
return prevfix+this.img(line,cmd)
+(this.checkbox?'<input type="checkbox" onclick="'+this.name+'.select(this)" />':'')
+this.img(ico)+' <a href="javascript:void(0)" href="javascript:void(0)" onclick="'+this.name+'.click(this);" '
+'key="'+name+'" val="'+value+'" >'
+name+type+(value==''?'':' = ')+value+'</a>'
},
img:function(src,attr){/* img HTML构造 */
return '<img src="'+src+'" src="'+src+'" '+(attr||'')+' />';
},
click:function(item){/* 子项点击统一回调 */
if(this.hot)this.hot.className='';
this.hot=item;
this.hot.className='hot';/* 切换选中项 */
this.onclick(item);
},
format:function(txt,compress/*是否为压缩模式*/){/* 格式化JSON源码(对象转换为JSON文本) */
if(/^\s*$/.test(txt))return this.msg('数据为空,无法格式化! ');
try{var data=eval('('+txt+')');}
catch(e){
JE.editUI.style.color='red';
return this.msg('数据源语法错误,格式化失败! 错误信息: '+e.description,'err');
};
JE.editUI.style.color='#000';
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+=This.indent;/* 缩进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);
this.countInfo='共处理节点<b>'+nodeCount+'</b>个,最大树深为<b>'+maxDepth+'</b>';
return draw.join('');
},
msg:function(text,type){/* 编辑状态或者错误通知 */
if(!this.msgUI)return alert(text);
with(new Date)var now=([getHours(),getMinutes(),getSeconds()].join(':')).replace(/\b\d\b/g,'0$&');
this.msgUI.innerHTML='<div>['+now+']   '+text.replace(/\n/g,'<br/>')+'</div>';
this.msgUI.className=type;
},
show:function (ico,id){/* 显隐树节点 */
var subView=ico.parentNode.parentNode.childNodes[1].style,J=this.ico;
if(subView.display=='none'){
subView.display='';
ico.src=J[id];
}else{
subView.display='none';
ico.src=J[id+'c'];
};
},
select:function (sender){
var sub=sender.parentNode.parentNode.getElementsByTagName("INPUT");
for (var i=0;i<sub.length;i++ ) {sub[i].checked=sender.checked;}
}
};
JE.add=function(){
this.msg('功能添加中...*_^');
}
JE.editItem=function(){
this.msg('功能添加中...*_^');
}
JE.begin=function(){/* 设置UI控件关联响应 */
var $=function (id){return document.getElementById(id)};
/* 关联UI */
JE.editUI=$("json_eidit");
JE.msgUI=$("json_editInfo");
JE.treeUI=$("tree");
var updateUI=$("update");
var auto=$("autoUpdate");
var fontSize=$("fontSize");
/* 单击树子项 */
JE.onclick=function(item){
var key='键名: <input value="'+item.getAttribute('key')+'" />',
val=' 键值: '+(item.getAttribute('val')==''?'成员列表':'<input value="'+item.getAttribute('val')+'" />'),
add='<button onclick="'+this.name+'.add(this)">新增</button>',
edit='<button onclick="'+this.name+'.editItem(this)">修改</button>';
JE.msg(key+val+add+edit,'info');
}
/* 监听代码变化事件 */
JE.editUI.oninput=JE.editUI.onpropertychange=function (){
if(JE.formating)return;/* 格式化不刷新树 */
if(/^\s*$/.test(this.value))return JE.msg('请输入JSON格式的代码!');;
clearTimeout(JE.update);
try{JE.data=eval('('+this.value+')');
}catch(e){
JE.editUI.style.color='red';
return JE.msg("源代码有错误: "+e.description+' , 如果正在编辑中, 请忽略此消息!','err');
};
JE.editUI.style.color='#000';
if(auto.checked||JE.firstUp){/*若同步*/
JE.msg('语法正确,正在重新构造树,请稍候...','busy');
JE.update=setTimeout(function(){
JE.toTree();
},450);
}else{
JE.msg('语法正确,请点击刷新,或者打开视图同步开关,或者继续编辑!')
}
return true;
};
if(window.ActiveXObject)
document.execCommand("BackgroundImageCache", false, true);
/* 拦截Tab,自动格式化 */
JE.editUI.onkeydown=function (){
if(event.keyCode==9){$('format_indent').onclick();event.returnValue=false;};
JE.code=this.value;
}
/* 格式化 */
var format=function(compress){
var code=JE.format(JE.editUI.value,compress);
JE.formating=true;
if(code)JE.editUI.value=code;
JE.editUI.focus();
setTimeout(function(){JE.formating=false;},1000);
return code;
}
/* 工具栏按钮 */
$('format_indent').onclick=function (){if(format())JE.msg('完成缩进风格转换,'+JE.countInfo)}
$('format_compress').onclick=function (){if(format(true)!=undefined)JE.msg('完成紧凑风格转换,'+JE.countInfo);}
updateUI.onclick=function (){
JE.firstUp=true;
JE.editUI.onpropertychange()?JE.msg('成功刷新视图!'):JE.msg('数据有误,刷新失败!','err')
JE.firstUp=false;
};
$('clear_txt').onclick=function (){JE.editUI.value=JE.treeUI.innerHTML='';JE.editUI.focus();}
auto.onclick=function (){JE.msg('自动同步视图功能'+(this.checked?'开启':'关闭!'));};
/* 另存为 */
if(/*@cc_on !@*/true){$('save_as').style.display='none'};
$('save_as').onclick=function (){
var d=document,w=d.createElement('IFRAME');
w.style.display="none";
d.body.appendChild(w);
setTimeout(function(){
var g=w.contentWindow.document;
g.charset = 'utf-8';
g.body.innerHTML=JE.editUI.value;
g.execCommand("saveas",'', "json.txt") ;
},1);
}
};
/* 从这里开始 */
window.onload=function (){
JE.begin();
}
// --></script>

(0)

相关推荐

  • 用js实现的DIV+CSS编辑器代码

    DIV+CSS编辑器 var sInitColor = null; function callColorDlg(obj){ if (sInitColor == null) var sColor = dlgHelper.ChooseColorDlg(); else var sColor = dlgHelper.ChooseColorDlg(sInitColor); sColor = sColor.toString(16); if (sColor.length 在线DIV+CSS编辑器 类/标签/I

  • 百度编辑器从Json对象中取值,完成初次渲染,在编辑器内画表格

    第一次做企业级应用,感觉一点:对逻辑必须要非常明确,而且有了很多与之前不一样的概念. 在百度编辑器中,如何完成从服务器取值,来渲染出表格?这里需要先console.log(editor);在官方API中已经告诉我们写入的方法是setContent(),这里只要能传入我们最终拼好的的字符串,即可以在初始化中,绘制出我们想要的任何节点. 再send()完成之后,onreadystatechange = function(){},先上一段AJAX的代码.这段AJAX是消除游览器兼容,从尼古拉斯的书中学

  • JS限制文本框只能输入数字和字母方法

    限制只能输入数字 复制代码 代码如下: // ---------------------------------------------------------------------- // <summary> // 限制只能输入数字 // demo: $(".onlyNum").onlyNum(); 限制使用了onlyNum类样式的控件只能输入数字 // </summary> // --------------------------------------

  • js实现文本框中输入文字页面中div层同步获取文本框内容的方法

    本文实例讲述了js实现文本框中输入文字页面中div层同步获取文本框内容的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.o

  • js实现文本框选中的方法

    本文实例讲述了js实现文本框选中的方法.分享给大家供大家参考.具体如下: 这段javascript代码可解决文本框获得焦点,即使得文本框的内容被选中. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www

  • js限制文本框只能输入中文的方法

    本文实例讲述了js限制文本框只能输入中文的方法.分享给大家供大家参考.具体如下: 让文本框只能输入中文的方法及代码,如果你不小心输入了英文,它会自动倒回去,清空你的输入,直至你输入了中文它可会继续,很有意思,也很实用,当注册一些资料的时候可以来提升输入的准确度. 运行效果如下图所示: 具体代码如下: <html> <head> <title>让一个文本框只能输入汉字的方法</title> <meta http-equiv="Content-T

  • JS模仿编辑器实时改变文本框宽度和高度大小的方法

    本文实例讲述了JS模仿编辑器实时改变文本框宽度和高度大小的方法.分享给大家供大家参考.具体如下: 这里演示JS模仿编辑器中实时改变文本框大小,包括宽度和高度的方法,在一些在线编辑器,比如eWebEditor中,就有一个功能,让文本框不断的增大或减小,以适应页面的大小,这个功能是如何实现的呢?请您参考一下这个程序,相信你会从中获益. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-editor-cha-width-height-codes/

  • js实现文本框宽度自适应文本宽度的方法

    本文实例讲述了js实现文本框宽度自适应文本宽度的方法.分享给大家供大家参考.具体如下: 一个会随着输入文本框的字符多少而自动增加宽度的JS代码,当我们在文本框中输入字符的时候,如果文本框的宽度定义太小的话,那么我们输入的字符将会被隐藏,本段代码实现了文本框会自动适应输入文字的多少,它会自动加长. 运行效果如下图所示: 具体代码如下: <!Doctype HTML PUBLIC "-//W3c//DTD Html 1.0 Transitional//EN"> <html

  • js显示文本框提示文字的方法

    本文实例讲述了js显示文本框提示文字的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <

  • 学习js在线html(富文本,所见即所得)编辑器

    你要的是所见即所得HTML编辑器,简单来说需要几个基本步骤: 1,需要一个可以编辑同时又可显效果的编辑框.textarea不行,它只能用来输入纯文本,不能显示颜色.斜体之类的文字样式,就像记事本.你可以使用iframe来实现,修改iframe的designMode属性使其可以被编辑. 复制代码 代码如下: <iframe id="myEditer" width="100%" height="150px"></iframe>

随机推荐