JSON 编辑器实现代码


Posted in Javascript onDecember 06, 2009

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

JSON 编辑器实现代码 
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>
Javascript 相关文章推荐
基于json的jquery地区联动效果代码
Jul 06 Javascript
通过Javascript将数据导出到外部Excel文档的函数代码
Jun 15 Javascript
JS判断当前日期是否大于某个日期的实现代码
Sep 02 Javascript
输入框过滤非数字的js代码
Sep 18 Javascript
js实现的动画导航菜单效果代码
Sep 10 Javascript
jQuery日历插件datepicker用法详解
Mar 03 Javascript
javascript中apply、call和bind的使用区别
Apr 05 Javascript
javascript鼠标滑过显示二级菜单特效
Nov 18 Javascript
vue页面使用阿里oss上传功能的实例(一)
Aug 09 Javascript
详解使用jest对vue项目进行单元测试
Sep 07 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
Mar 23 Javascript
解决vuecli3中img src 的引入问题
Aug 04 Javascript
JS 控制非法字符的输入代码
Dec 04 #Javascript
对采用动态原型方式无法展示继承机制得思考
Dec 04 #Javascript
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
Dec 04 #Javascript
javascript 跳转代码集合
Dec 03 #Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
Dec 03 #Javascript
javascript json 新手入门文档
Dec 03 #Javascript
js 屏蔽鼠标右键脚本附破解方法
Dec 03 #Javascript
You might like
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
php+ajax实现无刷新动态加载数据技术
2015/04/28 PHP
codeigniter实现get分页的方法
2015/07/10 PHP
php实现scws中文分词搜索的方法
2015/12/25 PHP
php基于openssl的rsa加密解密示例
2016/07/11 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
2016/11/14 PHP
php unicode编码和字符串互转的方法
2020/08/12 PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
2018/01/29 PHP
PHP获取ttf格式文件字体名的方法示例
2019/03/06 PHP
javascript 类方法定义还是有点区别
2009/04/15 Javascript
IE6 fixed的完美解决方案
2011/03/31 Javascript
js实现大转盘抽奖游戏实例
2015/06/24 Javascript
JS拖拽插件实现步骤
2015/08/03 Javascript
使用控制台破解百小度一个月只准改一次名字
2015/08/13 Javascript
微信小程序开发图片拖拽实例详解
2017/05/05 Javascript
nodejs前端自动化构建环境的搭建
2017/07/26 NodeJs
VUE+Element UI实现简单的表格行内编辑效果的示例的代码
2018/10/31 Javascript
详解小程序不同页面之间通讯的解决方案
2018/11/23 Javascript
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
node.js express框架实现文件上传与下载功能实例详解
2019/10/15 Javascript
python用字典统计单词或汉字词个数示例
2014/04/22 Python
pycharm 使用心得(三)Hello world!
2014/06/05 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
Python3一行代码实现图片文字识别的示例
2018/01/15 Python
python写一个md5解密器示例
2018/02/23 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
Tretorn美国官网:瑞典外套和鞋类品牌,抵御风雨
2018/07/19 全球购物
3个CCIE对一个工程师的面试题
2012/05/06 面试题
移风易俗倡议书
2014/04/15 职场文书
感恩教育活动总结
2014/05/05 职场文书
英语专业毕业生求职信
2014/05/24 职场文书
教师批评与自我批评心得体会
2014/10/16 职场文书
大学生十八大感想
2015/08/11 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
Django使用redis配置缓存的方法
2021/06/01 Redis