今天處理table表格下的<tr>中的<td>標簽中幾個按鈕點擊事件,三個按鈕分別要實現置頂,取消置頂,刪除操作。其中EditRequest()函數是寫好的ajax方法,一開始我是這么寫的:
$('.cancel-top').click(function(){ var pid = $(this).parents('tr').find(".pid").text(); if(confirm("確定要取消置頂嗎?")){ EditRequest(pid,'not_top'); } }); $('.to-top').click(function(){ var pid = $(this).parents('tr').find(".pid").text(); if(confirm("確定要置頂此主題帖嗎?")){ EditRequest(pid,'top'); } }); $('.del-post').click(function(){ var pid = $(this).parents('tr').find(".pid").text(); var _this = $(this); if(confirm("確定要刪除此主題帖嗎?")){ EditRequest(pid,'del',_this); } });
那么問題來了,好像三個事件函數都差不多,這樣寫的話產生了大量重復代碼,並不覺得它足夠優雅,於是決定改寫它:
1 var config = [ 2 {'classNm':'cancel-top','msg':'取消置頂','type':'not_top'}, 3 {'classNm':'to-top','msg':'置頂此帖','type':'top'}, 4 {'classNm':'del-post','msg':'刪除此帖','type':'del'}, 5 ]; 6 for(var i=0;i<3;i++){ 7 $('.'+config[i].classNm).click(function(){ 8 var _this = $(this), 9 pid = $(this).parents('tr').find(".pid").text(); 10 if(confirm("確定要"+config[i].msg+"嗎?")){ 11 EditRequest(pid,config[i].type,_this); 12 } 13 }) 14 };
顯然click事件處理函數內部是獲取的i值總是3,此時我想大聲呵呵。說來慚愧,我並沒有深入理解javascript中的作用域問題。腦補了一下后,將for語句改寫如下:
1 for(var i=0;i<3;i++){ 2 (function(i){ 3 $('.'+config[i].classNm).click(function(){ 4 var _this = $(this), 5 pid = $(this).parents('tr').find(".pid").text(); 6 if(confirm("確定要"+config[i].msg+"嗎?")){ 7 EditRequest(pid,config[i].type,_this); 8 } 9 }) 10 })(i); 11 };
使用閉包就可以巧妙地解決問題,但是總覺得jQuery有自己的辦法而不是使用難以理解的麻煩的閉包。於是又腦補了一下后,改寫如下:
1 for(var i=0;i<3;i++){ 2 $('.'+config[i].classNm).click({index:i},function(e){ 3 var _this = $(this), 4 pid = $(this).parents('tr').find(".pid").text(); 5 if(confirm("確定要"+config[e.data.index].msg+"嗎?")){ 6 EditRequest(pid,config[e.data.index].type,_this); 7 } 8 }) 9 };
jQuery中的事件處理函數都可以自帶event參數的,往往都是默認的一些參數。當然也可以手動添加一些參數到它的data屬性里面,正是利用了這一點達到了我的目的。突然就精簡了,是不是又進步了一點點了呢?!哈哈哈…