之前寫了一個自動增列元件,點到最後一列時會自動產生新的一列,套用了 jQuery 之後,發現既有的欄位都有生效,但新增一列出來的欄位就沒生效,我嘗試在新增一列後,重新執行一次 jQuery 的 API (bind 方法),但仍然無效。

經追蹤 jQuery 的 source 後,我發現只要有被 jQuery “碰過”的 element ,都會加上 jQuery1200220xxx =”xx” 的屬性,應該是 jQuery 為了加快第二次 access 該 element 的速度所留下的”痕跡”,而我的自動增列因為是複製最後一列的所有 html 產生新的 element,當然這個 jQuery 留下的 “痕跡” 也會被一併複製,所以新產生出來的 element 仍然擁有舊的 jQuery ID,雖然有重新執行 JQuery 的 API (其實是要 bind 一些方法),但 JQuery 發現在 cache 中已存在該 ID 了時就會自動 skip 掉,所以新列就完全沒 bind 到任何方法。
解決方法:
過濾新列的 html ,將 JQuery 的 ID 殺掉,如下:

var expr=/jQuery\d+=(\"|\')?\d+(\"|\')?/g ;
    return s.replace(expr,"");

這樣就會將 jQuery1239298329=”23″ 這類的 ID 去掉了。

加了這行後,一切正常了 !

 

jquery 提供一個很 fancy 的 selector幫助我們很容易的找到要控制的 dom 元件。例如:當我相找出nextSign… 開頭的欄位時,過去作法需要把 form1 下所有elements找出再走訪每個element,判斷名稱才能找出。

<form name=”form1”>

<input type=”text” name=”nextSignEmpNo” value=””>

<input type=”text” name=”nextSignDeptNo” value=””>

<input type=”text” name=”docNo” value=””>

</form>

javascript:

for(var i=0;i<form1.elements.length; i++) {
  if ( form1.elements(i).name.indexOf(”nextSign”)==0) {
        alert( form1.elements(i).value );
  }
}

jQuery做法:

$(“input[name^=’nextSign’]).each(function(){
  alert( $(this).val() );
})

$(“input[name^=’nextSign’]) 是指所有input的name只要是 nextSign 開頭的都抓出來,若然有1個form以上,並且不同form有相同欄位名稱時,這樣抓可能會出錯,所以需要再把 form考量進來。

$(“form[name=’form1’] input[name^=’nextSign’]).each(function(){
  alert( $(this).val() );
})

jquery 的 selector 有個特色,可以將不同的 selector 組合使用,這樣幾乎沒有找不到的DOM物件。

以 attribute 抓物件方式還有

[attribute*=value] 只要出現value關鍵字

[attribute$=value] value關鍵字結尾

[attribute!=value] value關鍵字不能出現

像如果要抓出下面這兩個欄位

<input type=”text” name=”nextSignEmpNo_v1” value=””>

<input type=”text” name=”nextSignDeptNo_v1” value=””>

$(“input[name$=’_v1’]).each(function(){
  alert( $(this).val() );
})
 

要將 javascript 裡某些字串先拿掉,放個 key,執行某些動作後再放回去的做法。

譬如:
var a=”Stephen  <file name=’a*+m?’/><file [name]=’(a)’/> King !”;
var rslt = a.match(/\<.*?\>/g);
for(var i=0;i<rslt.length;i++){
     a= a.replace(rslt[i],”Z”+i);
};
a最後會等於 ”Stephen Z0Z1 King !”
在執行 replace(regexp, “new word”);時
regexp若是放入字串,就不會視作 regular expression, 完整範例如下:
 

在 JavaScript 中要宣告變數,我們知道有下面這些宣告方式:

var foo = "" ;
var myObject={};
var myFunc=function() {

};
var myArray=[];
//...略

以上皆屬於靜態宣告,即我必須”寫死”變數的名稱。如果需要動態的宣告 10 個變數,譬如是:
myVar1, myVar2, myVar3…,這時你可以很勤勞的寫10個宣告statement,

var myVar1, myVar2, myVar3...

若不想這麼累,那可考慮動態宣告,在這之前先讓大家了解一件事,所有 JavaScript 的變數其實都是放在 window 這個物件底下,

var myVar = "abc";
alert( window.myVar ) ; // 跳出 "abc"

window 也是物件,動態宣告變數,其實就是在 window 底下動態加入屬性,所以可以寫成:

window.myVar1="abc";
window.myVar2="def";

寫這樣跟自己直接宣告變數好像又一樣,

var varName = "myVar1";
window[varName] = "abc";
alert(myVar1); // 跳出 "abc"
for(var i=0;i<10;i++){
  window["myVar"+i]="ABC"+i;
}
alert( myVar9 ) // 跳出 "ABC9"

以 window[變數名稱]=... 宣告變數,就能達到真正的動態宣告。

既然動態宣告變數,而 function 又是變數的一種,就可以動態宣告 function 囉。

var myFuncName="myFunc";
window[myFuncName]=function(){
   alert('this is my function');
};
myFunc() ;
 

JavaScript 語法很不嚴謹,光宣告物件就有幾種寫法,譬如可以寫成:

var myObject=new Object();
myObject.myAttrib="ABC";
alert(myObject.myAttrib);​

同樣效果,也可以寫成:

var myObject={};
myObject.myAttrib="123";
alert(myObject.myAttrib);

甚至在宣告物件時,同時也宣告屬性:

var myObject={
    myAttrib:"456"
};
alert(myObject.myAttrib);

物件屬性可以是物件、陣列:

var hotel={
    room:{
       roomNo:"H203"
    }
};
alert(hotel.room.roomNo); // H203

var hotel={
    rooms:[{
           roomNo:"H203"
        },{
           roomNo:"P130"
        }
    ]
};
alert(hotel.rooms[1].roomNo); // P130

物件屬性甚至可以是個 function,在 javascript的世界裡,function 也是看成 object

var hotel={
    reserveRoom:function(roomNo){
            alert("Room No."+roomNo+" is reserved!");
    }
};
hotel.reserveRoom("M093") ;

物件屬性除了以靜態方式宣告,也可以動態加入,我可以在宣告物件時只定義了一個屬性,程式執行期間動態加入其他新的屬性。

 
var hotel={
    reserveRoom:function(roomNo){
            alert("Room No."+roomNo+" is reserved!");
    }
};
hotel.cancelReserve=function(roomNo){
  alert("Room No."+roomNo+" reservation has be cancelled !");
}
hotel.reserveRoom("M093") ;

 

假如想加入的屬性名稱是動態組成的,譬如我想加入 myMethod1,myMethod2,myMethod3..myMethod10 共10個方法,可以這樣寫:

 
// 加入動態名稱的 function
var hotel={
};
for(var i=1;i<=10;i++){
   hotel["myMethod"+i]=function() {
       alert("myMethod is called!");
   }
}
hotel.myMethod3() ;
hotel.myMethod8() ;​​​​

物件內屬性之間的調用,可用 this.$屬性名稱 的方式調用同個物件的其他屬性,

 
// 加入動態名稱的 function
var hotel={
   name:'遠來大飯店',
   welcome:function(){
        alert("歡迎來到 "+this.name );
   }
};
hotel.welcome()​​​​

以下是這次的範例程式,可以直接run哦。

© 2012 Saihong Blog Suffusion theme by Sayontan Sinha