JS_Detail和Discipline

编码原则

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>&nbsp;地图加载中…</h1>'

});

};

function unBlockMap(){

$.unblockUI();

}

//递减sentinal,如果接收数据完毕,则解除block

function
minusCheckHangZero(){

if(hangCount==0){

unBlockMap();

return;

}

hangCount--;

if(hangCount==0){

unBlockMap();

return;

}

};

$(document).ready(function(){

console.log("map.html
ready() is triggered");

mapAppObj=new
mapObject();

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

function
loopCookies(){

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 对象

字符串包含

  1. var Cts = "bblText";
  2. if(Cts.indexOf("Text") >= 0 )
  3. {
  4. alert('Cts中包含Text字符串');
  5. }

JSON和字符串互相转换

Json转
字符串:var last= JSON.stringify(obj)

字符串转Json:   JSON.parse(string)


String Object Methods

Method

Description

charAt()

Returns the character at the specified index

charCodeAt()

Returns the Unicode
of the character at the specified index

concat()

Joins two or more strings, and returns a copy of the joined
strings

fromCharCode()

Converts Unicode
values to characters

indexOf()

Returns the position of the first found occurrence of a
specified value in a string

lastIndexOf()

Returns the position of the last found occurrence of a
specified value in a string

localeCompare()

Compares two strings in the current locale

match()

Searches for a match between a regular expression and a
string, and returns the matches

replace()

Searches for a match between a substring (or regular
expression) and a string, and replaces the matched substring with a new
substring

search()

Searches for a match between a regular expression and a
string, and returns the position of the match

slice()

Extracts a part of a string and returns a new string

split()

Splits a string into an array of substrings

substr()

Extracts the characters from a string, beginning at a
specified start position, and through the specified number of character

substring()

Extracts the characters from a string, between two specified
indices

toLocaleLowerCase()

Converts a string to lowercase letters, according to the
host's locale

   

toLocaleUpperCase()

Converts a string to uppercase letters, according to the
host's locale

   

toLowerCase()

Converts a string to lowercase letters

toString()

Returns the value of a String object

toUpperCase()

Converts a string to uppercase letters

trim()

Removes whitespace from both ends of a string

valueOf()

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");

var
key=_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;

}

var
left=$(input).css("left");

var
top=$(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;

}

var
tempStr = "<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>";

var
xmlHttp = null;

try {
xmlHttp = new XMLHttpRequest(); }

catch (e) {//
Internet Explorer

try {

xmlHttp = new
ActiveXObject("Msxml2.XMLHTTP");

}

catch (e) {

xmlHttp = new
ActiveXObject("Microsoft.XMLHTTP");

}

}

xmlHttp.onreadystatechange = function () {

if (this.readyState
== 4 && this.status == 200) {//callback

var
xlsUrl = 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=" + new
Date().toLocaleString();

xmlHttp.open("POST", url,
true);

xmlHttp.send(tempStr);

$("#imgExportExcel").addClass("dNone");

$blockUI({message:'<h1><img
src="../img/common.busy.gif"/>&nbsp;查询中...</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"){

var
tempTb=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=new
Date();

submit(url,
postData,function(rData){

var end=new
Date();

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="关?键¨¹字Á?"
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;

function
bindUIEvents(){

$(".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被点击.

function
bindUIEvents(){

$(".row").on("click",function(e){

console.log("row is
clicked");

console.log("cell
is:"+$(e.target)[0].innerHTML);

});

}

<table><tr
class="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();

return
value;

};

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;

var
privateVisit=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">

var
testObj=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">

function
CTest1(){

try{

privateLog();

var
privateLog=function(){

console.log("privateLog
has been called");

};

}

catch(e){

console.log(e.descripiton);

}

}

function
CTest2(){

try{

this.publicLog();

this.publicLog=function(){

console.log("publicLog
has been called");

};

}

catch(e){

console.log(e.description);

}

}

</script>

<body>

<script type="text/javascript">

var
test1=new CTest1();

var
test2=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">

function
CTest1(){

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">

var
test1=new CTest1();

</script>

</body>

</html>

控制台:

call privateA()

privateA has been
called

call _this.privateA() in privateB

对象不支持“privateA”属性或方法

call this.privateB()

对象不支持“privateB”属性或方法

Javascript 类 (时刻,时间类)

//时º¡À刻¨¬

this.hour =
parseInt(h);

this.minute
= parseInt(m);

this.totalMinutes = this.hour * 60 + this.minute; //分¤?钟¨®总Á¨¹数ºy,ê?用®?于®¨²排?序¨°

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
= "已°?选?时º¡À段?:";

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{

var
resultStr="第"+shopMisUtil.autoObj.responseNum+"个响应,";

shopMisUtil.autoObj.responseNum++;

//获取发起shop

var
sourceKey=results.keyword;

var
sourceShop=function(){

for(var
j=0;j<=shopMisUtil.shops.length-1;j++){

if(shopMisUtil.shops[j].Address==sourceKey){

return
shopMisUtil.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);}

}

function
startNextLoop(fromNum){

var
toNum;

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){

var
tempAr=[];

var
tempNum=0;

var
cur=tempNum+shopMisUtil.updateObj.updatedNum;

while(tempNum<shopMisUtil.updateObj.upNumPerLoop&&cur<shopMisUtil.shops.length){

var
oneShop=shopMisUtil.shops[cur];

tempAr.push(oneShop);

tempNum++;

}

shopMisUtil.submit(url,{cmd:1,data:tempAr,condition:null},function(rData){

var
result=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 、bdLoadJSLocalnet 、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+-*/%!@#^&{}()<>.,;'你好";

var
esed=escape(psw);

var
unesed=unescape(esed);

console.log("escaped:"+esed);

console.log("unesed:"+unesed);

缺点:

(1)不加密字符数字

结论:

不用。

字符 和Unicode 转换

Unicode即万国码,全球所有字符。共65536个。

使用0-65535这些数值,建立字符-数值一一映射。

结论:比escape强,但需要进一步编码

charCodeAt-将字符转成 unicode数值

fromCharCode-将unicode数值转成 字符

//var str='1234qwER你好';

 StrUTF8数组

function
toUtf(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

function
toStr(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序列,不存放密码

上一篇:Linux设备文件简介(转载)


下一篇:Java使用foreach遍历集合元素