編碼原則
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
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 對象
字符串包含
- 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");
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"/> 查詢中...</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 、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+-*/%!@#^&{}()<>.,;'你好";
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你好';
Str轉UTF8數組
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]
BCDEveWU佱妎
ende.decrypt("BCDEveWU佱妎")
1234qweTFD你好
sha256散列 密碼
評定:
比plain Text安全。
其它網站賬戶安全。
引用:sha256.js
加密:
var str="1234qwER你好世界";
sha256_digest(str)
"40dcee1b329f479172692e6213bbcf43d7c2229d49be5565ae811db3b84fb4ec"
結果:
64位的hash序列。
特點:不可逆
數據庫存放hash序列,不存放密碼
