编码原则
Js控件代码3部曲
(1)设置元素的 状态 在onready中添加
(2)设置元素的 动作, 每个动作 封装成 function(enclosure)
(3)remove load之前 删除方法,属性
DeferList1次和 3次DeferList 14s vs 29s
1次:
var tempAr=[];
var queryTask=new esri.tasks.QueryTask(getQueryUrl(0));//station
var query=new esri.tasks.Query();
query.outSpatialReference=mapAppObj.map.spatialReference;
query.outFields=["*"];
query.returnGeometry=true;
query.where="isFinished=1";
tempAr.push(queryTask.execute(query));
queryTask=new esri.tasks.QueryTask(getQueryUrl(1));//line
tempAr.push(queryTask.execute(query));
queryTask=new esri.tasks.QueryTask(getQueryUrl(2));//sections
tempAr.push(queryTask.execute(query));
var deferList=new dojo.DeferredList(tempAr);
deferList.then(function(results){
时间:
4次:
initStationFeatures()
initSectionFeatures()
initLineFeatures()
时间:
引用类型, 指向变量控制在1
举例:
var arr=[obj,obj2,obj3,obj4]
var newArr=[];
for(var i=0;i<=arr.length-1;i++){
if(…){
newArr.push(arr[i])
}
}
Return newArr
Obj: arr[0],newArr[0],指向。
这样性能低于 arr[0]
引用类型 军规 让指向变量只有一个,
Case1:
newFeatures 和features都指向 features
var newFeatures=[];//仅入 京之区
for(var i=0;i<=features.length-1;i++){
var oneFeature=features[i];
var name=oneFeature.attributes.NAME;
时间:523ms
case2:
只有features
for(var i=0;i<=features.length-1;i++){
var oneFeature=features[i];
var name=oneFeature.attributes.NAME;
//Yellow
if(name=="昌平区"||name=="丰台区"){
oneFeature.setSymbol(new
oneFeature.setInfoTemplate(null);
targetLayer.add(oneFeature);
}
时间:219ms
2M到4M 和 2s到4s
若不会耗尽客户端的内存。用空间换时间。
动态的部分越少越好
Iframe越少越好
原因:iframe导致内存泄露.
click军规-禁止在代码中触发事件
事件金留给用户处理
函数三部曲
--1检查异常值
--2执行运算
--3返回结果
页面两部曲
--1.编写HTML
--2. documentReady中请求数据
--3.documentReady中绑定事件
代码检查F12
探查器->开始采样->调用树
说明:计数,执行次数
包含时间,每次执行的毫秒数
代码不好改,是因为不自然
不要在HTML中onclick
原因:1不好维护
2 副作用很多
300*300 table显示 性能要义:
(1) 不要在td中加div
(2) 一次把300*300的html写好后,再添加到dom元素中。(只用一次append()或html())
(3) 尽量不要给td设置id,id个数90000时,对性能影响很大.
多进程控制
多个异步进程,如何同步
//总结:第一个异步请求发出前blockUI。 Sentinal++; 每个接收函数中将
Sentinal--,并判断sentinal是否是0;如果是,解除block。执行后续操作。
var hangCount=0;
function blockMap(){
$.blockUI({
message : ‘<h1><img src="../img/common/busy.gif"></img> 地图加载中…</h1>‘
});
};
function unBlockMap(){
$.unblockUI();
}
//递减sentinal,如果接收数据完毕,则解除block
functionminusCheckHangZero(){
if(hangCount==0){
unBlockMap();
return;
}
hangCount--;
if(hangCount==0){
unBlockMap();
return;
}
};
$(document).ready(function(){
console.log("map.html ready() is triggered");
mapAppObj=newmapObject();
mapAppObj.initBaseMap();
blockMap();
//进程1
hangCount++;
mapAppObj.featuresDictionary.getLinesInOd();//获取OD中所有line
//进程2
hangCount++;
mapAppObj.featuresDictionary.getStationsInOd();//获取OD中所有Station
//进程3
hangCount++;
mapAppObj.featuresDictionary.getAllFeatures(function(){
mapAppObj.lineLayer.init();//依赖进程3
mapAppObj.stationLayer.init(false);//依赖进程3
minusCheckHangZero();
});//callback end
//进程4
mapAppObj.labelLayer.addToMap();
});
数据加载前,必须BlockUI
setInterval和setTimeout
闪烁效果
$(function(){
var bIn=setInterval(function(){
if($("#dv").hasClass("dNone")){
$("#dv").removeClass("dNone");
}
else{
$("#dv").addClass("dNone");
}
},300);
setTimeout(function(){
clearInterval(bIn);
},2000);
});
Confirm Alert Prompt
(1)var flag=confirm(“确定离开此页面”);
(2)alert(“未能获取数据”);
(3)
var str=prompt(“请输入工程师姓名”,”姓名”);
Window_Anchor对象
新建选项卡
<a class="div1ADetail" href="‘+onePoi.detailUrl+‘" target="_blank">详情>></a>
备注:去掉下划线 text-decoration:none
伪造新建选项卡
var $a=$(‘<a href="http://www.baidu.com" target="_blank"></a>‘);
$a.appendTo("body");
$a[0].click();
$a.remove();
Location对象_路径符号
获取网站根目录
//获取根目录名 /odGIS
function getRootName(){
var path = document.location.pathname.substr(1);
path = "/" + path.substr(0, path.indexOf("/"));
return path;
}
/到端口号;./当前页的父目录;../当前目录向上
Cookie对象
遍历cookies
客户端:所有cookies存储在document.cookie中。
格式:co1=val1;col2=val2;col3=val3;
摘要:
取所有cookies |
document.cookie |
|
|
|
|
functionloopCookies(){
var cosStr=document.cookie;
if(cosStr==""){
console.log("no cookie exist");
return;
}
var cos=document.cookie.split(";");
for(var i=0;i<=cos.length-1;i++){
var cN=cos[i].split("=")[0];
var cV=cos[i].split("=")[1];
console.log("Name:"+cN+",Value:"+cV+"\n");
}
}
在baidu上执行效果:
Name:BAIDUID,Value:557D96D13E7C9662F7DCFD9E8C13FED1:FG
Name: BDRCVFR[DfWFxj3YnYn],Value:mk3SLVN4HKm
Name: CNZZDATA30080359,Value:cnzz_eid%3D2026158897-1392476638-http%253A%252F%252Fwww.baidu.com%252F%26ntime%3D1392859028%26cnzz_a%3D9%26sin%3Dnone%26ltime%3D1392852635349%26rtime%3D6
Name: BDRCVFR[feWj1Vr5u3D],Value:I67x6TjHwwYf0
Name: BD_CK_SAM,Value:1
Name: H_PS_PSSID,Value:5095_1447_5213_4264_4760_5244_5188
创建cookie
//源自w3school
http://www.w3school.com.cn/js/js_cookies.asp
创建cookie
function setCookie(c_name,value,expiredays)
{
var exdate=new Date()
exdate.setDate(exdate.getDate()+expiredays)
document.cookie=c_name+ "=" +escape(value)+
((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
}
获取cookie
function getCookie(c_name)
{
if (document.cookie.length>0)
{
c_start=document.cookie.indexOf(c_name + "=")
if (c_start!=-1)
{
c_start=c_start + c_name.length+1
c_end=document.cookie.indexOf(";",c_start)
if (c_end==-1) c_end=document.cookie.length
return unescape(document.cookie.substring(c_start,c_end))
}
}
return ""
}
String 对象
字符串包含
- var Cts = "bblText";
- if(Cts.indexOf("Text") >= 0 )
- {
- alert(‘Cts中包含Text字符串‘);
- }
JSON和字符串互相转换
Json转 字符串:var last= JSON.stringify(obj)
字符串转Json: JSON.parse(string)
String Object Methods
Method |
Description |
Returns the character at the specified index |
|
Returns the Unicode of the character at the specified index |
|
Joins two or more strings, and returns a copy of the joined strings |
|
Converts Unicode values to characters |
|
Returns the position of the first found occurrence of a specified value in a string |
|
Returns the position of the last found occurrence of a specified value in a string |
|
Compares two strings in the current locale |
|
Searches for a match between a regular expression and a string, and returns the matches |
|
Searches for a match between a substring (or regular expression) and a string, and replaces the matched substring with a new substring |
|
Searches for a match between a regular expression and a string, and returns the position of the match |
|
Extracts a part of a string and returns a new string |
|
Splits a string into an array of substrings |
|
Extracts the characters from a string, beginning at a specified start position, and through the specified number of character |
|
Extracts the characters from a string, between two specified indices |
|
Converts a string to lowercase letters, according to the host‘s locale |
|
Converts a string to uppercase letters, according to the host‘s locale |
|
Converts a string to lowercase letters |
|
Returns the value of a String object |
|
Converts a string to uppercase letters |
|
Removes whitespace from both ends of a string |
|
Returns the primitive value of a String object |
Form对象
属性名 |
取值 |
说明 |
action |
action=”test.jsp” |
提交哪个jsp或servlet |
method |
post get |
提交方式。 get缺点: (1)长度不可超过5k (2)以url形式出现在地址栏,不安全 |
enctype |
multipart/form-data |
以二进制形式提交。用于上传文件 |
Frame对象
Frame调用页面内,和页面内调用frame外
Frame调用内
document.getElementById("frameId").contentWindow.setQueryLayer("line, section, station");
页面内调用外
window.parent.receivefromGis(arrSendSubway);
Frame去除边框
"<iframe frame-border=‘0‘>< /iframe>"
Object对象
遍历对象的属性名
遍历属性名
var testObject={"Soul":"Shimada","Soul2":"Cozuka"};
for(var temp in testObject){
alert(temp);
}
//result: Soul, Soul2
Input对象
文本框自动补全
//搜索工具,input-button-tips
function searchTool(){
var input=null;//关键字
var button=null;//搜索
var tips=null;//下拉选项
var _this=this;
//初始化
this.init=function(inputDiv,butnDiv,tipsDiv){
console.log("searchTool.init is called");
if(inputDiv==null||inputDiv.tagName.toLowerCase()!="input"){
console.log("invalid para,function searchToo.init()");
return;
}
if(butnDiv==null||butnDiv.tagName.toLowerCase()!="input"){
console.log("invalid para,function searchToo.init()");
return;
}
if(butnDiv==null||tipsDiv.tagName.toLowerCase()!="div"){
console.log("invalid para,function searchToo.init()");
return;
}
input=inputDiv;
button=butnDiv;
tips=tipsDiv;
console.log("searchTool widgets validated");
//文本框获取焦点,显示tips
$(input).on("focus",function(){
console.log("input focus is triggered");
_this.showTips(true);
});
//文本框失去焦点
$(input).on("blur",function(e){
//onblur,e always be input itsself
//when tips.children.click caused inputBlur,
//if not delay, showTips(false) precede children().click,
//then unable to selected tip;
console.log("input blur triggered,hideTips delayed 200ms");
setTimeout(function(){
_this.showTips(false);
},200);
});
//关键字变更
$(input).on("keyup",function(){
console.log("input keyup is triggered");
_this.updateTips($(this).val());
_this.showTips(true);
});
$(button).on("click",function(){
console.log("search click is triggered");
varkey=_this.getKey();
console.log("关键字是:"+key);
_this.showTips(false);
});
//点击tips以外的区域,tips关闭
};//end初始化
//获取输入的关键字
this.getKey=function(){
return $.trim($(input).val());
};
//显隐备选项
this.showTips=function(flag){
console.log("showTips("+flag+") is called");
if(flag){
//显示
if($(tips).hasClass("dNone")){
if($(tips).children().length==0){
console.log("no children in tips,tips won‘t be showed");
return;
}
varleft=$(input).css("left");
vartop=$(input).css("top")+$(input).css("height");
console.log("tips location:"+left+","+top);
$(tips).removeClass("dNone");
}
else{return;}
}
else{$(tips).addClass("dNone");}
};
//清空提示项,解除点击事件
this.clearTips=function(){
console.log("clearTips is called");
var length=$(tips).children().length;
console.log("tips.childeren.length is:"+length);
$(tips).children().off("click");
$(tips).empty();
};
//更新tips
this.updateTips=function(key){
console.log("updateTips is called");
this.clearTips();
var stationTips=mapAppObj.stationIDNameObj.getSimilarStationNames(key);
console.log("tips get,"+$.toJSON(stationTips));
var tipsHtml="";
for(var i=0;i<=stationTips.length-1;i++){
tipsHtml+="<p class=‘similarItem‘>"+stationTips[i]+"</p>";
}
$(tips).html(tipsHtml);
$(".similarItem").on("click",function(){
console.log("tipItem "+this.innerHTML+" is clicked");
$(input).val(this.innerHTML);
_this.showTips(false);
});
};
}
发送打印数据
(1)点击打印
this.exportGrid =function(){
if (this.grid.store == null) {
alert("尚未进行OD分析,无法导出表格");
return;
}
var data = this.grid.store.data;
if(data.length == 0) {
alert("尚未进行OD分析,无法导出表格");
return;
}
vartempStr = "<Xml dateTimeStr=‘" + $("#spanDateTimeTips")[0].innerText + "‘>";
for (var i = 0; i <= data.length - 1; i++) {
tempStr += "<Route id=‘" + data[i].id + "‘ OriginName=‘" + data[i].OriginName + "‘ DestinationName=‘" + data[i].DestinationName + "‘ TransferName1=‘" + data[i].TransferName1 + "‘ TransferName2=‘" + data[i].TransferName2 + "‘ TransferName3=‘" + data[i].TransferName3 + "‘ TransferName4=‘" + data[i].TransferName4 + "‘ TransferName5=‘" + data[i].TransferName5 + "‘ Directions=‘" + data[i].Directions + "‘ Distance=‘" + data[i].Distance + "‘ TimeCost=‘" + data[i].TimeCost + "‘ StationCount=‘" + data[i].StationCount + "‘ CheckOutNum=‘" + data[i].CheckOutNum + "‘ ODPartition=‘" + data[i].ODPartition + "‘ ODTotal=‘" + data[i].ODTotal + "‘ Price=‘" + data[i].Price + "‘ ></Route>";
}
tempStr += "</Xml>";
varxmlHttp = null;
try { xmlHttp = new XMLHttpRequest(); }
catch (e) {// Internet Explorer
try {
xmlHttp = newActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}
}
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {//callback
varxlsUrl = this.responseText;
document.getElementById("xlsLink").setAttribute("href", xlsUrl);
document.getElementById("xlsLink").click(); //下载xls文件
unblockMapAppUI();
$("#imgExportExcel").removeClass("dNone");
}
else if (this.readyState == 4 && this.status == 500) {
alert("服务端处理excel异常");
console.log(this.responseText);
console.log(this.responseXML);
}
};
var url = "../ServerScript/Handlers/getODHandler.ashx?type=exportExcel&time=" + newDate().toLocaleString();
xmlHttp.open("POST", url, true);
xmlHttp.send(tempStr);
$("#imgExportExcel").addClass("dNone");
$blockUI({message:‘<h1><img src="../img/common.busy.gif"/> 查询中...</h1>‘});
};
key事件发生顺序
结论:down-press-up
$("#mLogin-inUsr").on("keydown",function(e){
console.log("keydown");
});
$("#mLogin-inUsr").on("keyup",function(e){
console.log("keyup");
});
//inUsr onChange
$("#mLogin-inUsr").on("keypress",function(e){
console.log("key press");
});
keydown-值未变
结论:keydown发生时,值未变
$("#mLogin-inUsr").on("keydown",function(e){
console.log("keydown");
console.log($.trim($("#mLogin-inUsr").val()));
});
keypress-值未变
$("#mLogin-inUsr").on("keypress",function(e){
console.log("keypress");
console.log($.trim($("#mLogin-inUsr").val()));
});
keyup-值已变
$("#mLogin-inUsr").on("keyup",function(e){
console.log("keyup");
console.log($.trim($("#mLogin-inUsr").val()));
});
Array对象
数组,排序, 升序和降序,删除
升序:
function sortFunction(a,b)
{
return a - b
}
降序:
function sortFunction (a,b)
{
return b- a
}
调用方式:
ar.sort(sortFunction);
备注:执行后,数组顺序将改变
中文按拼音顺序排序
//按站名排序
var sortGraphicsByName=function(b,a){
return b.attributes.NAME.localeCompare(a.attributes.NAME);
};
数组, pop和splice
Arr.pop() 删除并返回最后一个元素
Splice(i,1)删除第i个元素
删除1:
keys.splice(tempIndex, 1);//删除不限
备注:方法1得到的是剩余元素构成的数组。
删除2:
keys=keys.splice(tempIndex, 1);//删除不限
备注:方法2得到的是被删除元素形成的数组。
从数组中删除元素,loop必须用递减
数组拷贝
法1:
var arrB=arrA;
法2:
for(var i=0;i<=arrA.length-1;i++){
arrB.push(arrA[i]);
}
JS 数组合并排序
A:[1,3,5,7,9]
B:[1,3,6,8,10]
输出:
[1,3,5,6,7,8,9,10]
LocalStorage对象
只能存字符串
localStorage.setItem(‘test’,[1,2,3]);
取
localStorage.getItem(‘test’);
移除
localStorage.removeItem(‘test’);
Table对象
内存泄露
方案1:使用innerHTML清空table
添加900行后
Div.innerHTML=””之后
泄露大小:6M
泄露比率:6M/12M=50%
增删10次后内存:56M
每次增加比率:0.1/60.
方案2:使用deleteRow清空table
else if(e.target.id=="btnRemoveRows"){
vartempTb=document.getElementById("tbMemoCheck");
for(var i=tempTb.rows.length-1;i>=0;i--){
tempTb.deleteRow(i);
}
return false;
}
添加900行后:
DeleteRow之后:
泄露大小:6M
泄露比率:6M/12M=50%
增删10次后
泄露增值:7M-6M=1M;
每次增加比率:0.1/60.
结论:
使用innerHTML=””;
和deleteRow效率相同;
附录:代码
<style type="text/css">
#dvTableArea{
width:800px;
height:600px;
overflow:scroll;
}
#dvTableArea table{
border:1px solid #000;
}
td{
border:1px solid #000;
}
</style>
<script type="text/javascript">
window.onload=function(){
makeAndBind();
};
function clearRows(){
document.getElementById("dvTableArea").innerHTML="";
}
function appendRows(){
clearRows();
var innerString=‘<table id="tbMemoCheck" cellSpacing="0px">‘;
for(var i=0;i<=900;i++){
innerString+=‘<tr>‘;
for(var j=0;j<=10;j++){
var cellText="cell("+i+","+j+")";
innerString+=‘<td>‘+ cellText+‘</td>‘;
}
innerString+=‘</tr>‘;
}
innerString+=‘</table>‘;
document.getElementById("dvTableArea").innerHTML=innerString;
}
//javascript 的 make and bind
function makeAndBind(){
document.body.onclick=function(e){
if(e.target.tagName.toLowerCase()=="td"){
console.log(e.target.innerHTML+" is clicked");
return false;
}
else if(e.target.id=="btnAddRows"){
appendRows();
return false;
}
else if(e.target.id=="btnRemoveRows"){
clearRows();
return false;
}
return false;
}
}
</script>
</head>
<body class="tundra">
<div><input type="button" id="btnAddRows"value="添加行"><input type="button" id="btnRemoveRows" value="删除行"></div>
<div id="dvTableArea"></div>
</body>
</html>
Date对象
时刻差
结论:用于判断哪个方法执行时间长。 提高程序效率
var start=newDate();
submit(url, postData,function(rData){
var end=newDate();
console.log("请求rData时间:"+(end.getTime()-start.getTime())+"毫秒");
DOM事件
绑定
备注:不依赖javascript框架,拓展性极强.
请优先于jquery和dojo的绑定方式使用
function bindEvents(){
document.getElementById("inpTest").onfocus=function(){
console.log("inpTest is focused");
};
document.getElementById("inpTest").onblur=function(){
console.log("inpTest is blured");
};
document.getElementById("inpTest").onclick=function(){
console.log("inpTest is clicked");
};
/*不支持
document.getElementById("inpTest").onclick(function(){
console.log("inpTest is clicked");
});
*/
document.getElementById("btnUnBind").onclick=function(){
}
}
取消绑定
键盘事件 onkeypress
<input type="text" id="inpNameKey" value="关?键¨1字á?" onkeypress="checkKey(event)"
Onkeydowm,onkeyup 连选选择
function allowContinSel(e) {
if (e.keyCode == 16) {
alert("允¨许¨连续选择");
}
}
function forbidenContinSel(e) {
if (e.keyCode == 16) {
alert("连续选择终止");
}
}
</script>
</head>
<body class="claro" onkeydown="allowContinSel(event)" onkeyup="forbidenContinSel(event)">
On 绑定多次, Off关闭
<script type="text/javascript">
function bindClick(){
console.log("bindClick is called");
//on("click"), bind one, execute one. bind many times, execute manyTimes
$("#testDv").on("click",function(){
console.log("testDv is clicked");
});
}
//off, many times before, no on("click") after using off("click")
function unbind(){
$("#testDv").off("click");
}
$(document).ready(function(){
bindClick();
});
</script>
Console:
所有事件处理结束后 return false
Return false. 防止寻找其它handler
Blur事件 对象
序号 |
对象 |
是否能触发blue |
1 |
input type=”text” |
true |
|
input type=”button” |
|
|
|
|
2 |
span |
false |
|
label |
false |
冒泡和捕获
触发顺序
1. 当父元素和子元素都绑定了click,总是先触发最内层元素的click
2. 当只绑定了父元素click,通过e.target可以获取子元素
tr.click绑定 ,td.click绑定, 点击td
结论:
(1)td click后,会自动触发tr click
(2)在td.click 末尾添加 return false,可阻止tr.click
触发顺序是 最内层元素 依次向外
代码
<script type="text/javascript">
$(document).ready(function(){
bindUIEvents();
});
//情况1: td tr都绑定了click事件,点击td。
//发生顺序:td.click,->tr.click。
//屏蔽方式:td.click处理中添加return false;
functionbindUIEvents(){
$(".row").on("click",function(e){
console.log("row is clicked");
});
$("td").on("click",function(e){
console.log("td "+$(e.target)[0].innerHTML+" is clicked");
return false;
});
}
</script>
<style>
td{border:1px solid rgb(0,0,0);}
table{border-collapse:collapse;}
</style>
</head>
<body>
<table><tr class="row"><td class="col1">cell1</td><td class="col2">cell2</td><td class="col3">cell3</td></tr></table>
</body>
tr.click绑定,td不绑定,点击td
结论:
(1)tr.click被触发
(2)通过e.target可以获取到td
价值:
对大容器绑定一次, 容器里面的元素不绑定,通过r.target可在一个handler中处理所有事件。
//情况2:tr绑定click,td不绑定click。
//点击tr中的td, tr.click触发,通过 e.target能获取到是哪个td被点击.
functionbindUIEvents(){
$(".row").on("click",function(e){
console.log("row is clicked");
console.log("cell is:"+$(e.target)[0].innerHTML);
});
}
<table><trclass="row"><td class="col1">cell1</td><td class="col2">cell2</td><td class="col3">cell3</td></tr></table>
阻止事件向父元素传播
子元素click中:
return false;
DOM元素操作
删除
window.parent.document.body.removeChild(window.parent.document.getElementById("dvFrameOD"));
创建并绑定(入门)
说明:两种情况能找到创建的dom元素
-1. Var domA=document.createElement(“div”);
domA.onclick=function(){}; //
-2.var domB=document.createElement(“div”);
domB.innerHTML=”<input id=’input1’>”;
document.appendChild(domB);
//注意,append之后才能直接getElementById到
document.getElementById(“input1”).onclick=function(){
};
//javascript 的 make and bind
function makeAndBind(){
var operPane=document.createElement("div");
var innerString="";
for(var i=0;i<=2;i++){
var tempId=‘input‘+i.toString();
var value=‘input‘+i.toString();
innerString+=‘<input type="text" value=‘+value+‘ id=‘+tempId+‘>‘;
}
operPane.innerHTML=innerString;
document.getElementById("testDv").appendChild(operPane);
//备注:只有在append之后,getElementById才能获取到
for(var i=0;i<=2;i++){
if(document.getElementById("input"+i.toString())==null){
console.log("input"+i.toString()+" is not found");
continue;
}
document.getElementById("input"+i.toString()).onclick=function(e){
console.log(e.target.id+" is clicked");
};
}
}
创建并绑定 (一个容器,下辖多个元素)
说明:
创建div,div内用innerHTML创建3个input,
在div.onclick判断哪个子元素触发事件.
优点:只append一次.
只有一个onclick事件.
在appendChild之前也可绑定事件
适用于多层结构的情况
//javascript 的 make and bind
function makeAndBind(){
//div容器
var operPane=document.createElement("div");
var innerString="";
//div容器 子元素html
for(var i=0;i<=2;i++){
var tempId=‘input‘+i.toString();
var value=‘input‘+i.toString();
innerString+=‘<input type="text" value=‘+value+‘ id=‘+tempId+‘>‘;
}
operPane.innerHTML=innerString;
//在div的click中处理所有子元素的事件
operPane.onclick=function(e){
var id=e.target.id;
if(id!=""){//子元素被点击
console.log(id+" is clicked");
return false;
}
else{//div被点击
console.log("div 被点击");
return false;
}
}
//appendDiv
document.getElementById("testDv").appendChild(operPane);
}
创建并绑定(一个容器,下辖多个元素,元素下又辖元素)
三部曲:
-1 div.container=document.createElement(“div”);
-2 div.innerHTML=htmlString;
-3 div.onclick=function(e){
var targetId=e.target.id;
if(targetId==””){
}
Else if(){
}
}
备注:使用createElement创建的dom元素,在appendChild之前也可onclick
//javascript 的 make and bind
function makeAndBind(){
//div容器
var operPane=document.createElement("div");
var innerString="";
//div容器 子元素html
for(var i=0;i<=2;i++){
var tempId=‘Level1-‘+i.toString();
var value=‘Level1-‘+i.toString();
if(i!=2){
innerString+=‘<div type="text" value=‘+value+‘ id=‘+tempId+‘>‘+value+‘</div>‘;
}
else{
innerString+=‘<div type="text" value=‘+value+‘ id=‘+tempId+‘>‘;
for(var j=0;j<=2;j++){
var tempId=‘Level2‘+j.toString();
var value=‘Level2‘+j.toString();
innerString+=‘<input type="text" value=‘+value+‘ id=‘+tempId+‘>‘;
}
innerString+=‘</div>‘;
}
}
operPane.innerHTML=innerString;
//在div的click中处理所有子元素的事件
operPane.onclick=function(e){
var id=e.target.id;
if(id!=""){//子元素被点击
console.log(id+" is clicked");
return false;
}
else{//div被点击
console.log("大容器 被点击");
return false;
}
}
//appendDiv
document.getElementById("testDv").appendChild(operPane);
}
<body class="tundra">
<div id="testDv"></div>
</body>
清空元素下所有子节点
document.getElementById(graphicAddedTime).innerHTML="";
XMLHttpRequest和Ajax
AJAX军规
在url后面添加?time=一个不会重复的时间, 否则将受缓存影响
var url = "http://localhost/ODWeb/getODHandler.ashx?type=&time=" + new Date().toLocaleString();
xmlHttp.open("POST", url, true);
xmlHttp.send(postData);
AJAX GET
function sendReq() {
var xmlHttp = GetXmlHttpObject();
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4) {
alert(this.responseText); //call back snippets, use responseText for data
}
};
var url="photos.json";
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function GetXmlHttpObject() {
var xmlHttp = null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
AJAX POST
function sendReq() {
var xmlHttp = GetXmlHttpObject();
xmlHttp.onreadystatechange = function () {
if (this.readyState == 4) {
alert(this.responseText); //call back snippets, use responseText for data
}
};
var url = "../getODHandler.ashx";
xmlHttp.open("POST", url, true);
xmlHttp.send(postData);
}
function GetXmlHttpObject() {
var xmlHttp = null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
AJAX军规,异步请求 线数据,站数据,时间数据
3种请求无前后关系,
ajax(“linedata”,function(){ bindlineEvent();});
ajax(“stationdata”,function(){ bindstationEvent();});
ajax(“stationdata”,function(){ bindyearEvent();});
AJAX军规-加时间,防止读缓存
在url后面添加?time=一个不会重复的时间, 否则将受缓存影响
var url = "http://localhost/ODWeb/getODHandler.ashx?type=&time=" + new Date().toLocaleString();
xmlHttp.open("POST", url, true);
xmlHttp.send(postData);
动态Html字符串
动态background-position样式
$(document).ready(function(){
var htmlStr="";
for(var i=0;i<=9;i++){
htmlStr+=‘<div style="background:url(../img/markers.png) 0px ‘+(-(i*25)).toString()+‘px"></div>‘;
}
$("#testDiv").html(htmlStr);
});
备注:注意position数值,注意url引号。
效果
类和对象
Javascript 私有方法/公有方法
function testClass(){
this.publicHello=function(){
return "publicHello";
};
var privateHello=function(){//私有方法,obj.privateHello无法调用
return "privateHello";
};
this.callPrivate=function(){
var value=privateHello();
returnvalue;
};
this.callPrivate2=function(){
var value=this.privateHello();//调用私有方法不能用this
return value;
};
}
/*调用举例
* var testObj=new testClass();
* testObj.publicHello(); //"publicHello";
* testObj.privateHell():// undefined;
* testObj.callPrivate(); //"privateHello";
* testObj.callPrivate2(); //undefined;
*/
Javascript 访问公有成员(inside private M)
<html>
<head>
<title>private method 调用成员,public method 调用成员</title>
<script type="text/javascript">
function CTest(){
this.member="member of CTest";
var_this=this;
varprivateVisit=function(){
console.log("privateVisit, this.member is:"+this.member);
console.log("privateVisit,_this.member is:"+_this.member);
}
this.publicVisit=function(){
console.log("publicVisit,this.member is:"+this.member);
}
this.callPrivateVisit=function(){
privateVisit();
console.log("callPrivateVisit triggered privateVisit()");
}
}
</script>
</head>
<body>
<script type="text/javascript">
vartestObj=new CTest();
testObj.callPrivateVisit();
testObj.publicVisit();
</script>
</body>
</html>
控制台:
privateVisit, this.member is:undefined
privateVisit,_this.member is:member of CTest
callPrivateVisit triggered privateVisit()
publicVisit,this.member is:member of CTest
Javascript 私/公 访调顺序
<html>
<head><title>私/公 声调顺序</title></head>
<script type="text/javascript">
functionCTest1(){
try{
privateLog();
var privateLog=function(){
console.log("privateLog has been called");
};
}
catch(e){
console.log(e.descripiton);
}
}
functionCTest2(){
try{
this.publicLog();
this.publicLog=function(){
console.log("publicLog has been called");
};
}
catch(e){
console.log(e.description);
}
}
</script>
<body>
<script type="text/javascript">
vartest1=new CTest1();
vartest2=new CTest2();
</script>
</body>
</html>
控制台:
undefined
对象不支持“publicLog”属性或方法
结论:必须先声明,后调用
Javascript 调用私有方法
This.M(), _this.M() failed.
M() works;
<html>
<head><title>don‘t use this.method to call private method</title></head>
<script type="text/javascript">
functionCTest1(){
var _this=this;
var privateA=function(){
console.log("privateA has been called");
}
var privateB=function(){
console.log("call privateA()");
privateA();
console.log("\ncall _this.privateA() in privateB");
try{
_this.privateA();
}
catch(e){
console.log(e.description);//_this.privateMethod()不能调用私有方法
}
};
privateB();//第一次执行privateB()
try//第二次执行privateB();
{
console.log("\ncall this.privateB()");
this.privateB();
}
catch(e){
console.log(e.description);
}
}
</script>
<body>
<script type="text/javascript">
vartest1=new CTest1();
</script>
</body>
</html>
控制台:
call privateA()
privateA has been called
call _this.privateA() in privateB
对象不支持“privateA”属性或方法
call this.privateB()
对象不支持“privateB”属性或方法
Javascript 类 (时刻,时间类)
//时o?à刻¨?
this.hour = parseInt(h);
this.minute = parseInt(m);
this.totalMinutes = this.hour * 60 + this.minute; //分¤?钟¨?总á¨1数oy,ê?用??于?¨2排?序¨°
return this;
}
Moment.prototype.isSame = function (moment) {
if (this.hour == moment.hour && this.minute == moment.minute) { return true; }
else { return false; }
}
Moment.prototype.isBefore = function (moment) {
if (this.hour < moment.hour) { return true; }
else if (this.hour == moment.hour) {
if (this.minute < moment.minute) { return true; }
else if (this.minute == moment.minute) { return false; }
else { return false; }
}
else {
return false;
}
}
Moment.prototype.isAfter = function (moment) {
if (this.hour > moment.hour) { return true; }//7:00. 7:01
else if (this.hour == moment.hour) {
if (this.minute > moment.minute) { return true; }
else if (this.minute == moment.minute) { return false; }
else { return false; }
}
else {
return false;
}
}
//时段
function Period() {
if (arguments.length != 4 && arguments.length != 2) {return null;}
if (arguments.length == 4) {
var startH = arguments[0];
var startM = arguments[1];
var endH = arguments[2];
var endM = arguments[3];
if (startH > endH) { return null; }
else if (startH == endH) {
if (startM > endM) { return null; }
}
this.startMoment = new Moment(startH, startM);
this.endMoment = new Moment(endH, endM);
this.startMinutes = this.startMoment.totalMinutes;
this.endMinutes = this.endMoment.totalMinutes;
this.length = this.endMoment.totalMinutes -this.startMoment.totalMinutes;
return this;
}
else {
this.startMoment = arguments[0];
this.endMoment = arguments[1];
this.startMinutes = this.startMoment.totalMinutes;
this.endMinutes = this.endMoment.totalMinutes;
this.length = this.endMoment.totalMinutes -this.startMoment.totalMinutes;
return this;
}
}
/*
参数:
返回:
*/
Period.prototype.isSame = function (objPeriod) {
if (this.startMoment.isSame(objPeriod.startMoment) && this.endMoment.isSame(objPeriod.endMoment)) { return true; }
else { return false; }
}
Period.prototype.containMoment = function (moment) {
if ((this.startMoment.isSame(moment) || this.startMoment.isBefore(moment))&& (this.endMoment.isSame(moment) || this.endMoment.isAfter(moment))) {
return true;
}
else {
return false;
}
}
/*获取已选时段*/
function getPeriodArrayString(arrPeriods) {
var result = "已°?选?时o?à段?:";
arrPeriods.sort(sortPeriodsByStartMoment);
for (var i = 0; i <= arrPeriods.length - 1; i++) {
result += arrPeriods[i].startMoment.hour + ":" + arrPeriods[i].startMoment.minute + "-" + arrPeriods[i].endMoment.hour + ":" + arrPeriods[i].endMoment.minute + ",";
}
result = result.substr(0, result.length - 1);
return result;
}
JS时段合并
/*合并两个period
*/
function combineTowPeriod(last, prev) {
if (last.startMinutes > prev.endMinutes) {//左 离
return null;
console.log("0");
}
else if (last.startMinutes == prev.endMinutes) { //左共时刻
return (new Period(prev.startMoment, last.endMoment));
console.log("1");
}
//左部分相交
else if (last.startMinutes < prev.endMinutes && last.startMinutes > prev.startMinutes && last.endMinutes > prev.endMinutes) {
return (new Period(prev.startMoment, last.endMoment));
console.log("2");
}
//真包含
else if (last.startMinutes <= prev.startMinutes && last.endMinutes >= prev.endMinutes) {
return (new Period(last.startMoment, last.endMoment));
console.log("3");
}
//右部分相交
else if (last.endMinutes > prev.startMinutes && last.endMinutes < prev.endMinutes) {
return (new Period(last.startMoment, prev.endMoment));
console.log("4");
}
//右共时刻
else if (last.endMinutes == prev.startMinutes) {
return (new Period(last.startMoment, prev.endMoment));
console.log("5");
}
//右 离
else if (last.endMinutes < prev.startMinutes) {
console.log("6");
return null;
}
else {
alert("预期外组合出现");
return null;
}
}
/*描述:时段区间合并算法
*/
function simplifyPeriodArray(arrPeriods) {
if (arrPeriods.length <= 1) {return arrPeriods;}
var haschanged = false;
do {
for (var j = arrPeriods.length - 1; j >= 0; j--) {
arrPeriods.sort(sortPeriodsByLength); //重新排序
haschanged = false;
var longestP = arrPeriods[j];//从尾取最长
for (var i = j-1; i >= 0; i--) {//合并j之前的i
var newP = combineTowPeriod(longestP, arrPeriods[i]);
if (newP == null) { continue; }
else {
haschanged = true;
arrPeriods.splice(j, 1, newP); //替换最长
longestP = newP;
arrPeriods.splice(i, 1);//删除被合并
}
}//end for
} //end for
} while (haschanged);
}
JS 拷贝一个javascript对象/数组
背景:javascript对象都是引用类型.拷贝有两种方式:
方式1:重新构造javascript对象B,将A的属性逐个赋值到B上。
方式2:将A转成字符串,
创建对象B=JSON.parse(字符串)
下面介绍这种方式:
var jsonObj={x:101,y:102};
var tempObj=jsonObj;
tempObj.x=100;
console.log(jsonObj.x==tempObj.x);
var jsonStr=JSON.stringify(jsonObj);
var newObj=JSON.parse(jsonStr);
newObj.x=103;
console.log(jsonObj.x==newObj.x);
JS静态类 (JSON对象属性作为方法)
var staticClass={
sayHello:function(){
console.log("hello");
}
};
$(document).ready(function(){
staticClass.sayHello();
});
静态类方法A调用方法B
var staticClass={
sayHello:function(){
staticClass.getConstantPI();
},
getConstantPI:function(){
console.log(Math.PI);
}
};
拷贝/镜像应用
Copy步骤
1.找主页html,下载.
2. 从主页link和script建立对应的目录结构. 下载js,css文件
3.捕捉XMLHttpRequest Header头和url,data. 将reponseData存成json或者xml以供显示
Copy成果:
YYDA
应用举例
Script5 拒绝访问 (门户如何集成n个网站)
描述:
<html>
..<title>门户首页</title>..
…<iframe src=”跨域页.html”></iframe>..
</html>
<html>
..<title>跨域页.html</title>..
…<script src=”jquery.js”></>...
<script>
$(document).ready(function(){
});
</script>
</html>
报错;
Script 5:拒绝访问
$ 未定义
解决方式
<html>
..<title>门户首页</title>..
…<iframe src=”无jq跨域页.html”></iframe>..
</html>
<html>
..<title>无jq跨域页.html< /title>..
<iframe src=”jq页.html”></iframe>
</html>
<html>
<title>jq页.html<title>
<script src=”jquery.js”></script>
<script>
$(document).ready(function(){
});
</script>
</html>
4800个点,智能获取首坐标
代码清单:
(1)autoObj
(2)startNextLoop
(3)autoBind
---
//自动绑定, 用控制台,未UI
autoObj:{
//localSearchOption
searchOption:{
//回调函数
onSearchComplete:function(results){
try{
varresultStr="第"+shopMisUtil.autoObj.responseNum+"个响应,";
shopMisUtil.autoObj.responseNum++;
//获取发起shop
varsourceKey=results.keyword;
varsourceShop=function(){
for(var j=0;j<=shopMisUtil.shops.length-1;j++){
if(shopMisUtil.shops[j].Address==sourceKey){
returnshopMisUtil.shops[j];
}
}
return null;
}();
//未找到地址
if (results.getCurrentNumPois()==0){
sourceShop.Longitude=null;
sourceShop.Latitude=null;
resultStr+="\""+sourceKey+"\"未找到地址";
console.log(resultStr);
}
else{
//找到地址
sourceShop.Longitude=results.getPoi(0).point.lng;
sourceShop.Latitude=results.getPoi(0).point.lat;
resultStr+="\""+sourceKey+"\"坐标是:("+sourceShop.Longitude+","+sourceShop.Latitude+")";
console.log(resultStr);
}
//如果响应数目整数倍
var modVal=shopMisUtil.autoObj.responseNum%shopMisUtil.autoObj.reqPerLoop;
if(modVal==0){
startNextLoop(shopMisUtil.autoObj.responseNum);
}
return;
}
catch(e){
alert(e.description);
return;
}
}
},
responseNum:0,//已经回应多少条
reqPerLoop:1000,//每轮请求多少个 100个占用350M内存,1000 450M
startNum:0,//从第几个开始绑定
maxNum:0,//找到第几个商店就不找了 0- lengh-1
},
//自动绑定坐标
function autoBind(num){
//已绑定个数 0
shopMisUtil.autoObj.responseNum=0;
if(num==null){startNextLoop(0);}
else{startNextLoop(num);}
}
functionstartNextLoop(fromNum){
vartoNum;
if(shopMisUtil.autoObj.maxNum!=0){
toNum=(fromNum+shopMisUtil.autoObj.reqPerLoop-1)<(shopMisUtil.autoObj.maxNum)?(fromNum+shopMisUtil.autoObj.reqPerLoop-1):(shopMisUtil.autoObj.maxNum);
}
else{
toNum=(fromNum+shopMisUtil.autoObj.reqPerLoop-1)<(shopMisUtil.shops.length-1)?(fromNum+shopMisUtil.autoObj.reqPerLoop-1):(shopMisUtil.shops.length-1);
}
console.log(‘startNextLoop triggered, from ‘+fromNum+‘ to ‘+toNum);
for(var i=fromNum;i<=toNum;i++){
var oneShop=shopMisUtil.shops[i];
var oneKey=oneShop.Address;
var oneSearch=new BMap.LocalSearch(shopMisUtil.mp,shopMisUtil.autoObj.searchOption);
console.log("第"+i+"个地址\""+oneKey+"\"搜索开始");
oneSearch.search(oneKey);
}
}
4800个点,智能更新Oracle中坐标
原理:一次发送10个点。Ajax回调后,再发10个
为何只发10个:
发20个时,Svt中解析时出错,未查明原因。
代码:
updateObj:{
upNumPerLoop:10,//每次向tomcat更新多少个商店的位置,1次更新 //10, 480条/分钟
updatedNum:0//已更新位置
},
//更新所有商户位置
function updateAllShops(){
var url="../ShopCudes";
//逐个发送
shopMisUtil.updateObj.updatedNum=0;
var nextLoop=function(){
if(shopMisUtil.updateObj.updatedNum<shopMisUtil.shops.length){
vartempAr=[];
vartempNum=0;
varcur=tempNum+shopMisUtil.updateObj.updatedNum;
while(tempNum<shopMisUtil.updateObj.upNumPerLoop&&cur<shopMisUtil.shops.length){
varoneShop=shopMisUtil.shops[cur];
tempAr.push(oneShop);
tempNum++;
}
shopMisUtil.submit(url,{cmd:1,data:tempAr,condition:null},function(rData){
varresult=eval(rData)[0];
if(result.Done==true){
console.log("全商户,"+result.Info);
}
else{
console.log("全商户更新失败");
}
shopMisUtil.updateObj.updatedNum+=shopMisUtil.updateObj.upNumPerLoop;
nextLoop();
});
}
else{
console.log("全商户位置绑定完成");
}
};
nextLoop();
}
界面举例
组类UI处理方式
说明:
起点时段:shour,ehou,sminute,eminute,addedTimeO
终点时段:shour,ehou,sminute,eminute,addedTimeD
要进行的操作相同,仅仅DOM对象不同。
处理方式:设置5个对象,从界面条件,将5个对象指向。
var targetAddedTime = {};
var inpStartHour = {};
var inpStartMinute = {};
var inpEndHour = {};
var inpEndMinute = {};
var targetGraphicLayer = {};
if (this.id == "customOriginTime") {
targetAddedTime = $("#addedTimeOrigin")[0];
inpStartHour = $("#inpOHourStart")[0];
inpEndHour = $("#inpOHourEnd")[0];
inpStartMinute = $("#inpOMinuteStart")[0];
inpEndMinute = $("#inpOMinuteEnd")[0];
targetGraphicLayer = graLayerSelectO;
}
else {
targetAddedTime = $("#addedTimeDestination")[0];
inpStartHour = $("#inpDHourStart")[0];
inpEndHour = $("#inpDHourEnd")[0];
inpStartMinute = $("#inpDMinuteStart")[0];
inpEndMinute = $("#inpDMinuteEnd")[0];
targetGraphicLayer = graLayerSelectD;
}
后续语句将相同
报表样式设计
--1表头
--2左右有页边距
--3表头字体比表中数字明显
--4下页面有阴影效果
AMD 规范
概要
AMD= Asychronous Module Definition
异步模块规范。 作用是异步加载js类。比传统的(Legacy Module Definition)效率高。
实现了AMD规范的js库有RequireJS 、curl 、Dojo 、bdLoad、JSLocalnet 、Nodules 等。
AMD require
用于加载js模块
举例:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。
举例:
require([‘math‘], function (math) { math.add(2, 3);});
math.add()与math模块加载不是同步的,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。
AMD define
ASCII 128个
不可见:33个
可见:95个
字母 52个 |
数字行 26个 |
键盘右侧 16个 |
空格 1个 |
加密和解密
密码字符集
95个可显示字符中,除去空格。
即 94个
字母:52
数字行:26
右侧符号:16
结论:
不包含汉字
escape和unesace
escape原理:
(1)95个可显ASCII字符不变。其它字符变。
举例:
var psw="abcdefghijhlmnopqrstuvwxyz1234567890+-*/%!@#^&{}()<>.,;‘你好";
varesed=escape(psw);
varunesed=unescape(esed);
console.log("escaped:"+esed);
console.log("unesed:"+unesed);
缺点:
(1)不加密字符数字
结论:
不用。
字符 和Unicode 转换
Unicode即万国码,全球所有字符。共65536个。
使用0-65535这些数值,建立字符-数值一一映射。
结论:比escape强,但需要进一步编码
charCodeAt-将字符转成 unicode数值
fromCharCode-将unicode数值转成 字符
//var str=‘1234qwER你好‘;
Str转UTF8数组
functiontoUtf(str){
var result=[];
for(var i=0;i<=str.length-1;i++){
result.push(str.charCodeAt(i));
}
console.log(str +" utf8:"+result);
return result;
}
UTF8数组转Str
functiontoStr(arr){
var result="";
for(var i=0;i<=arr.length-1;i++){
result+=String.fromCharCode(arr[i]);
}
console.log(result);
return result;
}
1234qwER你好utf8:49,50,51,52,113,119,69,82,20320,22909
[49, 50, 51, 52, 113, 119, 69, 82, 20320, 22909]
toStr(ar)
1234qwER你好
举例:
ende.encrypt("1234qweTFD你好");
[49, 50, 51, 52, 113, 119, 101, 84, 70, 68, 20320, 22909]
BCDE??veWU佱妎
ende.decrypt("BCDE??veWU佱妎")
1234qweTFD你好
sha256散列 密码
评定:
比plain Text安全。
其它网站账户安全。
引用:sha256.js
加密:
var str="1234qwER你好世界";
sha256_digest(str)
"40dcee1b329f479172692e6213bbcf43d7c2229d49be5565ae811db3b84fb4ec"
结果:
64位的hash序列。
特点:不可逆
数据库存放hash序列,不存放密码