痛苦就是財富,這純屬扯蛋,痛苦之后的思考,才會是財富。知識也是一樣的道理,只知道一味的着急前進,卻忘記自己留下的腳印,如果沒有經過整理,思考,消化,吸收的過程,那它只是短暫的停留在自己的大腦里面。
這些看似簡單問題,是我正式從9月份正式踏入程序員行業以來經驗總結,若有什么不好的地方,希望大家一定要指出,兼聽則明,偏信則暗^_^
一,正確的使用eval()
第一次使用eval(),將后台寫的json格式字符串處理成json對象數組
var jsonstr = "{name:'test',age:18}";
var jsonobj = eval(jsonstr);
//拼接過程
錯誤提示:
SyntaxError: invalid label
寫到這里老是報錯,我心想,不對呀,怎么拿不到對象呢?
為什么會這樣?
原因在於:eval本身的問題。 由於json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,所以必須強制性的將它轉換成一種表達式。
加上圓括號的目的是迫使eval函數在處理JavaScript代碼的時候強制將括號內的表達式(expression)轉化為對象,而不是作為語句(statement)來執行。舉一個例子,例如對象字面量{},如若不加外層的括號,那么eval會將大括號識別為JavaScript代碼塊的開始和結束標記,那么{}將會被認為是執行了一句空語句。所以下面兩個執行結果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]
如何解決?
var josnobj = eval("("+jsonstr+")");
或者這樣
eval("var jsonobj = " + jsonstr);
二,ajax的緩存
相信有寫過圖片驗證碼或者經常調用ajax的同學會遇到這種問題。
示例:
id(主鍵) | pid | name |
1 | 11 | test1 |
2 | 11 | test2 |
如圖所示,pid為11 有兩個name test1,test2
第一次請求:
$.get("Handler.ashx",{mod:"get",pid:11},function(data){
alert(data);
});
顯示值: test1,test2
數據庫變動:
id(主鍵) | pid | name |
2 | 11 | test2 |
第二次請求:
$.get("Handler.ashx",{mod:"get",pid:11},function(data){
alert(data);
});
顯示值: test1,test2
為什么會這樣?
監視請求后發現,第二次請求壓根就沒有進入到Handler.ashx文件中去,這次請求直接進入緩存中,原來,我們的瀏覽器已經很聰明了,對於ajax請求的參數相同時,他會自動的保存上一次請求得到的數據,圖片的緩存也是這樣的,當你第一次打開一個網站時候,你會發現相當的慢,第二次打開的時候就相當的快,這個時候,瀏覽器不是去請求網站的服務傳送圖片,而是直接在本地的緩存中取到。
那如何解決?
既然你的參數是一樣的,那我讓參數不一樣就可以了。
$.get("Handler.ashx",{mod:"get",pid:11,random:Math.random()},function(data){
alert(data);
});
每次都會請求一個不同的參數,這樣瀏覽器會讓為是不同的請求而不會去緩存
另外一種方法是將$.get 換成$.ajax()
$.ajax()下有一個參數是這樣的,cache:false 將設置成不緩存
請參考:$.ajax()的參數
=============由於時間關系,暫時寫到這里,明天更新=============
三,json對象數組的前台拼接
正常的拼接過程:
var jsonstr = ""; //循環遍歷json數組 for(var i=0;i<jsonobjs.length;i++){ jsonstr +="<tr>"; jsonstr +="<td>"+jsonobjs[i].name+"</td>"; jsonstr +="<td>"+jsonobjs[i].age+"</td>"; jsonstr +="<td>"+jsonobjs[i].id+"</td>"; jsonstr +="<td>"+jsonobjs[i].createtime+"</td>"; jsonstr +="<td>"+jsonobjs[i].typename+"</td>"; //........n個屬性都拼接出來 jsonstr +="<td>"+jsonobjs[i].typeid+"</td>"; } //加入到table里面去 $("#tablelist").append(jsonstr);
老大看了以后,說你知道一個對象的屬性也可以循環獲取嗎?
不知道...
你知道你可以用數組來操作jsonstr字符串的拼接嗎?
不知道...
你知道你可以使用innerHTML來進行動態生成么?
不知道...
改后的代碼:
var strarr = []; var objlength = jsonobjs.length; for(var i=0;i<objlength ;i++){ strarr.push("<tr>"); for(var objproperty in jsonobjs[i]){ strarr.push("<td>"); strarr.push(jsonobjs[i][objproperty ]); strarr.push("</td>"); } document.getElementById("tblist").innerHTML = strarr.join(" "); }
為什么要這樣寫?
1.當進行大量的字符串拼接的時候,使用數組的push方法效率要遠遠的高於+=的操作符,這是我經過實驗和查資料后得到的結論,這個道理同樣適用於C#的StringBuilder的Append方法(話說面試里面就有考到過).
2.當進行大量的循環操作的時候,需要將數組length屬性拿出來,這樣避免每次循環都會進行數組長度的計算,可以提高效率.
3.在能使用動態生成DOM對象的時候,如果對象內有少量的節點,或者沒有結點,可以將結點提出來,然后使用innerHTML屬性進行賦值,這樣速度會快於appendChild()方法;
寫代碼,細節真的很重要。
另外推薦轉載:30個提高Web程序的執行效率的好經驗
四,動態生成的DOM對象
代碼示例:
<html> <head> <script type="text/javascript"> window.onload = function(){ //為btnadd注冊事件 document.getElementById("btnadd").onclick = function(){ document.getElementById('dvbody').innerHTML ="<span id='sptest'>mytest</span>"; } //為生成的span標簽注冊事件 document.getElementById("sptest").onclick = function(){ alert("click me"); } } </script> </head> <body> <input type='button' value='產生span標簽' id="btnadd" /> <div id="dvbody"> </div> </body> </html>
當我點擊span標簽的時候,壓根就沒有發生我要的效果呀?
為什么會這樣?
打開FireBug調試看看,我去,還是沒有任何的異常。看了半天,最后才明白,原來就是因為采用的動態生成的試,所以當離開btnadd.onclick注冊事件函數的時候為動態生成的sptest注冊事件,這樣脫離了他的范圍,壓根就找不到這個標簽.所以應該這樣寫
如何解決?
<html> <head> <script type="text/javascript"> window.onload = function(){ document.getElementById("btnadd").onclick = function(){ document.getElementById('dvbody').innerHTML ="<span id='sptest'>mytest</span>"; //保持上下緊密聯系一起 document.getElementById("sptest").onclick = function(){ alert("click me"); } } } </script> </head> <body> <input type='button' value='產生span標簽' id="btnadd" /> <div id="dvbody"> </div> </body> </html>
五,服務器控件隱藏
有些同學會問,呀,這你也出問題?Visiable=false不就可以了?對呀,頁面設置的他的可見性,在頁面加載完畢后,可以清晰看到已經不存在了。可是,如果你需要用JS操作這個控件時候,你會發現:
這個控件壓根就沒有了!
Visiable= true后查看的源代碼
Visiable=false查看的源代碼:
可以很清晰看到,div中壓根就沒有控件,那控件去哪里了呢?轉換成了ViewState了。
應該怎么做?
直接設置他的可見性那整個控件又沒有了,可是這個button卻只有一個Visiable屬性可以設置他的可見性,如何是好?我問我同事,我同事啥也沒有說,跑過來寫下這行代碼.
<asp:Button Text="text" runat="server" ID="btnaddo" Visible="true" style="display:none"/>
我去!竟然這么簡單,對呀,就是這么簡單。
如什么會這樣?
服務器控件的本質是什么?
網頁的實質就是html標簽+控件樹+一系列的控件的生命周期(方法),那服務器控件的本質所展現的內容也只能是html標簽,那既然是標簽,為什么不可以直接用style屬性呢?
六,sql的參數未賦值
1 string sqlstr = "select * from t_d_test where name=@name and age = @age and address = @address"; 2 SqlParameter[] parms = new SqlParameter[] 3 { 4 new SqlParameter("@name","test"), 5 new SqlParameter("@age",1), 6 new SqlParameter("@address","test1") 7 }; 8 DataTable dt = GetDataTable(sqlstr, parms);
這是一次很簡單的獲得DataTable過程,然后有的時候,sql語句需要動態的變化,
比如:
string sqlstr = "select * from t_d_test where name=@name and age = @age "; SqlParameter[] parms = new SqlParameter[] { new SqlParameter("@name","test"), new SqlParameter("@age",1), new SqlParameter("@address","test1") }; DataTable dt = GetDataTable(sqlstr, parms);
sql語句中很明顯只有兩個參數,但是我還去定義了parms為三個參數,執行的時候才發現,那叫一個速度慢哦,一直debug到最后一行方法時才發現,我壓根在sql語句中定義@address,最后速個的執行過程一直卡在這里。最后直接delete這個參數后,直接執行。
七,自增長列賦值插入[這個就不演示了- - 太可笑了]
八,服務器控件DropDownList的綁定后詭異的SelectIndexChange事件失效
在綁定數據后,服務器控件進行selectindexchange事件里面,查看不論怎么選擇,當前選中項的值一直都是不會變化的,為何?
在經過google后,發現問題所在DropDownList的子集item的屬性text 及value其實是一種字典的形式存在的,就是說一個Key對應唯一的Value,Value是不可以重復的!
解決方法:
保證value不重復