javascript json对象操作(基本增删改查)

模块已修改并发布,详细见 https://npmjs.org/package/jsing

/**
 * Json对象操作,增删改查
 *
 * @author 	lellansin
 * @blog 	www.lellansin.com
 * @version 0.1
 * 
 * 解决一些常见的问题
 * get/set 解决获取和设置时,无节点中断的问题
 * create  可以创建多级节点,若存在则覆盖新值
 * delete  删除节点及其子节点
 * print_r 格式化输出对象(调试用)
 * 实例见底部
 */

function Json() {

}

/**
 * 获取Json对象中的某个节点
 * 例如:json.get(Data, 'country', 'province', 'city');
 * 结果则返回 Data['country']['province']['city']
 * 无则返回false
 */
Json.prototype.get = function(obj, key) {
	var args = this.get.arguments;
	var result = obj;

	for (var i = 1; i < args.length; i++) {
		result = result[args[i]];
		if (result === undefined) {
			return false;
		};
	};
	return result;
};

/**
 * 设置Json对象中的某个节点
 * 例如:obj.set(data, "ENTRY", "FA_TOKEN_INVALID", 1234);
 * 将 data['ENTRY']['FA_TOKEN_INVALID'] 设置为1234
 * 成功true, 失败false
 */
Json.prototype.set = function(obj, key) {
	var args = this.set.arguments;
	if (ergodic_set(obj, args, 1)) {
		return true;
	} else {
		return false;
	}
}

/**
 * 在Json对象中创建节点(若存在则覆盖值)
 * 例如:obj.create(data, 'add', 'hello', 'test', 120);
 * 添加 data['create']['hello']['test'] 节点并设置值为 120
 * 成功true, 失败false
 */
Json.prototype.create = function(obj, key) {
	var args = this.create.arguments;
	if (ergodic_create(obj, args, 1)) {
		return true;
	} else {
		return false;
	}
}

/**
 * 在Json对象中删除节点
 * 例如:obj.delete(prods, 'grade', 'math');
 * 成功true, 失败false
 */
Json.prototype.delete = function(obj, key) {
	var args = this.delete.arguments;
	if (ergodic_delete(obj, args, 1)) {
		return true;
	} else {
		return false;
	}
}

/**
 * 返回Json对象的字符串形式(封装 ECMAScript 库函数)
 */
Json.prototype.getStr = function(obj) {
	return JSON.stringify(obj);
}

/**
 * 解析字符串返回Json对象(封装 ECMAScript 库函数)
 */
Json.prototype.getJson = function(str) {
	return JSON.parse(str);
}

/**
 * 格式化输出Json对象
 */
Json.prototype.print_r = function(obj) {
	console.log("{")
	ergodic_print(obj, "");
	console.log("}")
}

function ergodic_print(obj, indentation) {
	var indent = "	" + indentation;
	if (obj.constructor == Object) {
		for (var p in obj) {
			if (obj[p].constructor == Array || obj[p].constructor == Object) {
				console.log(indent + "[" + p + "] => " + typeof(obj) + "");
				console.log(indent + "{");
				ergodic_print(obj[p], indent);
				console.log(indent + "}");
			} else if (obj[p].constructor == String) {
				console.log(indent + "[" + p + "] => '" + obj[p] + "'");
			} else {
				console.log(indent + "[" + p + "] => " + obj[p] + "");
			}
		}
	}
}

function ergodic_set(obj, args, floor) {
	if (obj.constructor == Object) {
		for (var tmpKey in obj) {
			if (tmpKey == args[floor]) {
				if (floor < args.length - 2) {
					return ergodic_set(obj[tmpKey], args, floor + 1);
				} else {
					// 此时参数floor为倒数第二个,加1值为最后一个
					obj[tmpKey] = args[floor + 1];
					console.log("成功设置,返回true");
					return true;
				}
			}
		}
	}
}

function ergodic_create(obj, args, floor) {
	if (obj.constructor == Object) {
		for (var tmpKey in obj) {
			if (tmpKey == args[floor]) {
				if (floor < args.length - 2) {
					return ergodic_create(obj[tmpKey], args, floor + 1);
				} else {
					obj[tmpKey] = args[floor + 1];
					return true;
				}
			}
		}
	}
	// 节点不存在,创建新节点
	if (floor < args.length - 1) {
		var jsonstr = getJsonFormat(args[args.length - 1]);

		for (var i = args.length - 2; i > floor; i--) {
			jsonstr = '{"' + args[i] + '":' + jsonstr + '}';
		};

		// 使用eval解析第三方Json数据时,可能会执行恶意代码
		// var node = eval('(' + jsonstr + ')');
		var node = JSON.parse(jsonstr);
		obj[args[floor]] = node;
		return true;
	}
}

function ergodic_delete(obj, args, floor) {
	if (obj.constructor == Object) {
		for (var tmpKey in obj) {
			if (tmpKey == args[floor]) {
				if (floor < args.length - 1) {
					return ergodic_delete(obj[tmpKey], args, floor + 1);
				} else {
					delete obj[tmpKey];
					return true;
				}
			}
		}
	}
}


function getJsonFormat(param) {
	if (param.constructor == String) {
		return '"' + param + '"';
	} else {
		return param;
	}
}



/**
 * 使用实例
 */

var data = {
	OK: 200,
	FAIL: 500,
	ENTRY: {
		FA_TOKEN_INVALID: 1001,
		FA_TOKEN_EXPIRE: 1002,
		FA_USER_NOT_EXIST: 1003
	},
	GATE: {
		FA_NO_SERVER_AVAILABLE: 2001
	},
	CHAT: {
		FA_CHANNEL_CREATE: 3001,
		FA_CHANNEL_NOT_EXIST: 3002,
		FA_UNKNOWN_CONNECTOR: 3003,
		FA_USER_NOT_ONLINE: 3004
	}
};

var json = new Json();

console.log("获取Json中节点");
console.log(json.get(data, "OK")); // 200
console.log(json.get(data, "ENTRY", "FA_TOKEN_INVALID")); 	// 1001
console.log(json.get(data, "TEST", "获取没有的节点")); 		// false 没有的节点返回 false

console.log("设置Json中节点");
console.log(json.set(data, "ENTRY", "FA_TOKEN_INVALID", 1234));   // true 	设置成功
console.log(json.get(data, "ENTRY", "FA_TOKEN_INVALID")); 		  // 1234  	获取刚设置的节点
console.log(json.set(data, "ENTRY", "测试设置没有的节点", 1234)); // false 	设置失败

console.log("创建新的Json节点");
var prods = {
	'name': 'Alan',
	'grade': {
		'Chinese': 120,
		'math': 130,
		'competition': {
			'NOI': 'First prize'
		}
	}
};
console.log(json.create(prods, 'create', 'hello', 'test', 120)); 	 // true
console.log(json.create(prods, 'create', 'hello', 'test2', '通过')); // true

console.log("格式化输出节点");
json.print_r(prods);

console.log("删除节点");
console.log(json.delete(prods, 'grade', 'math')); 			// true
console.log(json.delete(prods, 'grade', 'competition')); 	// true
console.log(json.delete(prods, 'grade', '删除没有的节点')); // false
json.print_r(prods);

nodejs 实现 print_r


function ergodic(obj,indentation){
  var indent = "  " + indentation;
  if(obj.constructor == Array || obj.constructor == Object){

    for(var p in obj){
      if(obj[p].constructor == Array|| obj[p].constructor == Object){
        console.log(indent + "["+p+"] => "+typeof(obj)+"");
        console.log(indent + "{");
        ergodic(obj[p], indent);
        console.log(indent + "}");
      } else if (obj[p].constructor == String) {
        console.log(indent + "["+p+"] => '"+obj[p]+"'");
      } else {
        console.log(indent + "["+p+"] => "+obj[p]+"");
      }
    }
  }
}

function print_r(obj) {
  console.log("{")
  ergodic(obj, "");
  console.log("}")
}

var stu = {'name':'Alan','grade':{'Chinese':120,'math':130,'competition':{'NOI':'First prize'}}};

print_r(stu);

nodejs 实现 print_r

js 画图

原生js画图

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf8"> 
<title>js 画图</title> 
</head> 
<body> 
  <button onclick="testDrawCurve()">画曲线</button> 
  <button onclick="testDrawArc()">画弧线</button> 
  <button onclick="testDrawCircle()">画圆</button> 
  <button onclick="testDrawLine()">画线</button> 
  <button onclick="testDrawRectangle()">画矩形</button> 
  <button onclick="testDrawSector()">画扇形</button> 

  <div id="canvas"></div> 

<script type="text/javascript">
var div1 = document.getElementById("canvas");
// 画曲线测试
function testDrawCurve()
{
  div1.innerHTML = drawCurve(); 
}

// 画弧线测试
function testDrawArc()
{
  div1.innerHTML =drawArc(150,150,100,0,270,"blue")
}

// 画圆测试
function testDrawCircle()
{
  div1.innerHTML = drawCircle(200,200,150,"blue"); 
} 

// 画线测试
function testDrawLine()
{
  div1.innerHTML = drawLine(100,200,500,200,"yellow")+drawLine(300,100,300,400,"black")+drawLine(600,400,100,100,"violet")
}

// 画圆
function drawCircle(x0,y0,radius,color) 
{ 
  return drawArc(x0,y0,radius,0,360,color)
}

// 画矩形测试
function testDrawRectangle()
{
  div1.innerHTML = drawRectangle(200,100,600,200,"blue")+drawRectangle(100,200,400,500,"red")
}

// 画扇形测试
function testDrawSector()
{
  div1.innerHTML = drawSector(300,200,120,0,45,"red"); 
} 


/*
  画线
*/
function drawLine(x0,y0,x1,y1,color) 
{ 
  var rs = ""; 
  if (y0 == y1)  //画横线 
  { 
  if (x0>x1){var t=x0;x0=x1;x1=t}   
  rs = "<span style='top:"+y0+";left:"+x0+";position:absolute;font-size:1px;background-color:"+color+";height:1; width:"+Math.abs(x1-x0)+"'></span>"; 
  } 
  else if (x0 == x1)  //画竖线 
  { 
  if (y0>y1){var t=y0;y0=y1;y1=t}  
  rs = "<span style='top:"+y0+";left:"+x0+";position:absolute;font-size:1px;background-color:"+color+";width:1;height:"+Math.abs(y1-y0)+"'></span>"; 
  } 
  else 
  { 
    var lx = x1-x0
    var ly = y1-y0
    var l = Math.sqrt(lx*lx+ly*ly)
    rs = new Array(); 
    for (var i=0;i<l;i+=1) 
    { 
      var p = i/l; 
      var px = parseInt(x0 + lx*p); 
      var py = parseInt(y0 + ly*p); 
      rs[rs.length] = "<span style='top:"+py+";left:"+px+";height:1;width:1;position:absolute;font-size:1px;background-color:"+color+"'></span>"; 
    } 
    rs = rs.join(""); 
  } 
  return rs 
} 

/*
  画矩形
*/
function drawRectangle(x0,y0,x1,y1,color) 
{ 
  if (x0 == x1 || y0 == y1) return; 
  if (x0>x1) {var t=x0;x0=x1;x1=t} 
  if (y0>y1) {var t=y0;y0=y1;y1=t} 
  return "<table style='top:"+y0+";left:"+x0+";position:absolute'><td bgcolor="+color+" width="+(x1-x0)+" height="+(y1-y0)+"></td></table>"; 
} 

/*
  画扇形
*/
function drawSector(x0,y0,radius,startAngle,endAngle,color) 
{ 
  var rs = drawArc(x0,y0,radius,startAngle,endAngle,color);
  startAngle = startAngle/360*Math.PI*2; 
  endAngle = endAngle/360*Math.PI*2; 
  var startx=Math.sin(startAngle)*radius+x0; 
  var endx=Math.sin(endAngle)*radius+x0; 
  var starty=Math.cos(startAngle)*radius+y0; 
  var endy=Math.cos(endAngle)*radius+y0; 
  rs += drawLine(x0,y0,startx,starty,color);
  rs += drawLine(x0,y0,endx,endy,color);
  return rs; 
}

/*
  画弧线
*/
function drawArc(x0,y0,radius,startAngle,endAngle,color) 
{ 
  rs = new Array(); 
  tmpar = new Array(); 
  startAngle = startAngle/360*Math.PI*2; 
  endAngle = endAngle/360*Math.PI*2; 
  for (var i=startAngle;i<endAngle;i+=(1/radius))
  { 
    var dx = parseInt(Math.sin(i)*radius+x0); 
    var dy = parseInt(Math.cos(i)*radius+y0); 
    rs[rs.length] = "<span style='top:"+dy+";left:"+dx+";position:absolute;height:1;width:1;position:absolute;font-size:1px;background-color:"+color+"'></span>"; 
  } 
  return (rs.join("")); 
}

/*
  画曲线
*/
function drawCurve()
{
  var rs = new Array();
  for (var i=0;i<2*Math.PI;i+=.01)
  { 
    var x = parseInt(300-Math.sin(i)*100);
    var y = parseInt(300-Math.cos(i)*100);
    rs[rs.length] = "<span style='top:"+x+";left:"+(i*100+190)+" ;height:1;width:1;position:absolute;font-size:1px;background-color:blue'></span>"; 
    rs[rs.length] = "<span style='top:"+y+";left:"+(i*100+190)+" ;height:1;width:1;position:absolute;font-size:1px;background-color:blue'></span>"; 
  } 
  return rs.join(""); 
} 
</script> 

<!-- font-size:1px; for IE 6 -->
</body> 
</html>

end.x) {
var t = start.x;
start.x = end.x;
end.x = t;
}
rs = ““;
}
else if( start.x == end.x) //画竖线
{
if( start.y > end.y) {
var t = start.y;
start.y = end.y;
end.y = t;
}
rs = ““;
}else
{
var lx = end.x-start.x;
var ly = end.y-start.y;
var l = Math.sqrt(lx*lx+ly*ly);
rs = new Array();
for (var i=0;i<l;i+=1)
{
var p = i/l;
var px = parseInt(start.x + lx*p);
var py = parseInt(start.y + ly*p);
rs[rs.length] = "“;
}
rs = rs.join(“”);
}
$(“#canvas”).append(rs);
}

drawLine( {x:10,y:49}, {x:120,y:59}, “skyblue”);
–>

js jQuery 对象相互转换

js 的 getElementBy 系列获取不够方便, jQuery的过滤器很好用但是操作多个也不方便? 概念理清,混着用吧

<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>对象转换</title>
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<style type="text/css">
  #close_img:hover{
    cursor: hand;
  }
</style>

</head>

<body>

<div id="test"  style="width:300px; height:200px; background-color: orange"></div>
<div class="article" style="width:300px; height:200px; background-color: blue"></div>
<div class="article" style="width:400px; height:200px; background-color: skyblue"></div>
<div class="article" style="width:200px; height:200px; background-color: green"></div>

<script type="text/javascript">

// 直接用$() 将js的变量包住即可变成jQuery对象使用
var obj = document.getElementById('test'); 
alert("test 的高度为" + $(obj).height() + "px"); 


// jquery对象转js对象,直接在其后加上[0]即可
var display = $("#test")[0].style.width;
alert("test 的高度为" + display + "px");


// js与jquery对象混用
var list = $(".article");
var content = "";
for (var i = 0; i < list.length; i++) {
	content +="第 "+i+" 篇文章div 高" +
			 $(list[i]).css("height") + " 宽" +
			  $(list[i]).css("width") + "n";
};
alert(content);

</script>

</body>
</html>

js 设置鼠标光标形状

auto(default) 默认值。浏览器根据当前情况自动确定鼠标光标类型。
col-resize 有左右两个箭头,中间由竖线分隔开的光标。用于标示项目或标题栏可以被水平改变尺寸。
crosshair 简单的十字线光标。
all-scroll 有上下左右四个箭头,中间有一个圆点的光标。用于标示页面可以向上下左右任何方向滚动。
move 十字箭头光标。用于标示对象可被移动。
help 带有问号标记的箭头。用于标示有帮助信息存在。
no-drop 带有一个被斜线贯穿的圆圈的手形光标。用于标示被拖起的对象不允许在光标的当前位置被放下。
not-allowed 禁止标记(一个被斜线贯穿的圆圈)光标。用于标示请求的操作不允许被执行。
pointer(hand) 竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。
progress 带有沙漏标记的箭头光标。用于标示一个进程正在后台运行。
row-resize 有上下两个箭头,中间由横线分隔开的光标。用于标示项目或标题栏可以被垂直改变尺寸。
text 用于标示可编辑的水平文本的光标。通常是大写字母 I 的形状。
vertical-text 用于标示可编辑的垂直文本的光标。通常是大写字母 I 旋转90度的形状。
wait 用于标示程序忙用户需要等待的光标。通常是沙漏或手表的形状。
*-resize 用于标示对象可被改变尺寸方向的箭头光标。
w-resize | s-resize | n-resize | e-resize | ne-resize | sw-resize | se-resize | nw-resize
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js 光标设置</title>
</head>

<body>
<input type="button" value="auto" onclick=SetCursor("auto") /> 
<input type="button" value="col-resize" onclick=SetCursor("col-resize") /> 
<input type="button" value="row-resize" onclick=SetCursor("row-resize") /> 
<input type="button" value="all-scroll" onclick=SetCursor("all-scroll") /> 
<input type="button" value="crosshair" onclick=SetCursor("crosshair") /> 
<input type="button" value="move" onclick=SetCursor("move") /> 
<input type="button" value="help" onclick=SetCursor("help") /> 
<input type="button" value="no-drop" onclick=SetCursor("no-drop") /> 
<input type="button" value="not-allowed" onclick=SetCursor("not-allowed") />
<input type="button" value="pointer" onclick=SetCursor("pointer") /> 
<input type="button" value="progress" onclick=SetCursor("progress") /> 
<input type="button" value="text" onclick=SetCursor("text") /> 
<input type="button" value="vertical-text" onclick=SetCursor("vertical-text") /> 
<input type="button" value="wait" onclick=SetCursor("wait") /> 
<input type="button" value="w-resize" onclick=SetCursor("w-resize") /> 

<div id="test" style="width:600px; height:200px; margin: 0 auto; background-color: blue; color:#FFF;">移动鼠标到此查看效果</div>   


</body>

<script   language="Javascript">   
function SetCursor(str){   
  document.getElementById('test').style.cursor=str;
}   
</script>

</html>

效果演示

function SetCursor(str){
document.getElementById(‘test’).style.cursor=str;
}

移动鼠标到此查看效果

js 按键获取

原生 js 按键获取

 document.onkeydown = function() {

    if (event.ctrlKey == true && event.keyCode == 90) {//Ctrl+Z
        event.returnvalue = false;
        // $("btnSave1").click(); //ID
        alert("Ctrl+Z 被按下");
    }

    if (event.ctrlKey == true && event.keyCode == 89) {//Ctrl+Y
        event.returnvalue = false;
        // window.location.href="SetInfo.aspx?ChId=1&ColId=1"; //ID
        alert("Ctrl+Y 被按下");
    }
};

这样清掉了别的所有的事件。而且比如在火狐上的话,firebug会出一大堆的错误信息,一按下ctrl键其实就能看到浏览器收到了很多的ctrl键值。定义一个按ctrl的flag,然后抬起就至false。其他的按键统统return false的话,原生js也可以做。不过感觉有点粗暴。还是用jQ吧。

使用 jQuery 按键获取

$(document).keydown(function (e) {
    if (e.which === 17){
        isCtrl = true;
        $("#status").text("Ctrl 被按下!");
    }
    $("#status2").text(e.which);
    if (e.which === 90 && isCtrl === true) {
        alert("Ctrl+Z!");
    	$("#status2").text("就不来。。气死你");
    }
    if (e.which === 89 && isCtrl === true) {
        alert("Ctrl+Y!");
    }
}).keyup(function (e) {
    if (e.which === 17){
        isCtrl = false;
        $("#status").text("Ctrl 已抬起!");
	}
});

上述代码,在IE6上都能跑,但是不知道为什么不能在IE8上alert消息,博主试了好久,结果发现事件已经触发了,就是没alert,莫名其妙的IE系列。

js/jQuery 获取图片宽高

js

<script type="text/javascript">
	var myImg = new Image();
	myImg.src = "images/pingtan1.jpg";	
	myImg.onload = function(){
		// 自身宽高
		var map_w = this.width;
		var map_h = this.height;
		alert("图片 宽: "+map_w+" 高: "+map_h)
	}
</script>

jQuery

<script type="text/javascript">
$(document).ready(function(){

	$("#map").load(function () {
		
		// 窗口宽高
		var height = $(window).height();
		var width = $(window).width();
		// 自身宽高
		var map_w = this.width;
		var map_h = this.height;
		// 居中坐标
		var t_pos = (height - map_h)/2 +"px";
		var l_pos = (width - map_w)/2 +"px";
		// 设置居中
		$("#map_div").css({
			position: "absolute", 
			left: l_pos, 
			top: t_pos });
	});
});
</script>

一些闲话

chrome浏览器中如果要在jquery的 $(document).ready中拿不到到图片宽高,常规解决方案是在 $(window).load 的时候拿
貌似jQuery不准备做低IE的兼容了博主用的jq 1.9 在 IE居然不行,这个问题原生 js 兼容性更高吧