本周大部分空閒時間在整理 jQuery 筆記, 因為去年底從市圖借來的幾本書也該清一清, 趕快還掉 (雖然半年來都沒人借~~~). 整理筆記很花時間很累, 但這是一個反芻的過程, 可以更透徹檢驗是否真的會用, 而且以後要複習也很快. 九月份要接新增的工作, jQuery 可以幫上一些忙.
阿蘭因尿路感染住院近兩周, 週四醫院通知可出院, 由機構接回, 費用約兩萬. 今年已是第三次, 之前醫生說過對於身心障礙人來說衰退比一般人快, 五十歲相當於老人了. 近期國泰業務員詢問月配息 3.8% 的儲蓄險, 考慮將到期定存轉購此商品, 用以支付部分機構照料費用.
為了避免一時忘記繳大樓管理費被列入欠繳名單, 我去年底改成預繳下個月, 但還是覺得每個月都要準備零錢很麻煩, 所以前天就將今年剩下的管理費都預繳了, 以後年底就預繳次年的全部管理費, 管委會有預收款好辦事, 而且我也省時省事, 畢竟時間比甚麼都寶貴.
上回向公司樓下擺攤的買的兩個藍芽音箱我覺得是很久的庫存貨, 開始用沒多久電池就沒電, 今天拆開機箱發現裡面的鋰電池居然沒編號 (盒裝標示電池容量 520mAh), 只好上露天隨便找個容量大一點又塞得下去的來換 :
本周看完韓劇便利店新星, 這部兼具搞笑與感人效果 (娛樂紓壓還不錯), 改編自網路漫畫 (韓劇越來越多這種), 崔大賢 (池昌旭飾) 最終辭掉總公司代表職務回來當加盟店店長, 丁新星 (金裕貞) 也從農場回來當店經理了, 我覺得崔大賢的網路漫畫家朋友韓達植應該就是作者自己吧!
下周菁菁開學, 我又要開始早睡早起了.
2020年8月30日 星期日
2020年8月29日 星期六
2020年8月28日 星期五
市圖還書 3 本
本周還書 3 本 :
這本 R 語言與商業應用寫得不錯, 精簡又有料. Miss Q 這本特別股的書很紅, 我預約了好久才借到, 但我覺得特別股中大概中鋼特我比較中意 (有保證配息), 金融特別股都有期限.
這本 R 語言與商業應用寫得不錯, 精簡又有料. Miss Q 這本特別股的書很紅, 我預約了好久才借到, 但我覺得特別股中大概中鋼特我比較中意 (有保證配息), 金融特別股都有期限.
反應: |
2020年8月25日 星期二
已被廢棄的 jQuery 物件方法
最近在整理 jQuery 語法時注意到 bind() 事件綁定方法已被廢棄 (deprecated), 於是到 jQuery 官網查詢, 發現自 v1.3 版後還有蠻多選擇器, 物件方法, 以及工具函數 (頂層命名空間的 utilities) 陸續被廢棄, 例如 :
選擇器 :
參考 :
# https://api.jquery.com/category/deprecated/
# https://api.jquery.com/category/removed/
選擇器 :
- :first
- :last
- :eq()
- :lt()
- :gt()
- :even
- :odd
- load()
- unload()
- toggle()
- bind()
- unbind()
- delegate()
- undelegate()
- error()
- size()
- die()
- live()
- jQuery.now()
- jQuery.type()
- jQuery.proxy()
- jQuery.sub()
- jQuery.holdReady()
- jQuery.isNumeric()
- jQuery.isWindow()
- jQuery.isFunction
- jQuery.isArray
- jQuery.unique()
- jQuery.parseJSON()
- jQuery.fx.interval
- jQuery.support
- jQuery.browser
- jQuery.boxModel
參考 :
# https://api.jquery.com/category/deprecated/
# https://api.jquery.com/category/removed/
反應: |
2020年8月24日 星期一
jQuery 常用技法整理
最近因為改寫公司作業自動化工具的需要重新複習 jQuery, 同時把向市圖借的 jQuery 書籍摘要整理一下趕快還掉, 以免佔用我的書架. 參考書目如下 :
jQuery 的 API 參考 :
# https://api.jquery.com/
jQuery 的語法很簡單, 就是先用工廠函數 $() 以選擇器取得元素的 jQuery 物件 (集合), 再呼叫其物件方法 :
- 鋒利的 jQuery (佳魁)
- 打造 jQuery 網頁風暴 (佳魁)
- jQuery 應用程式設計極速上手 (上奇)
- jQuery 高手精技 (旗標)
- jQuery 實戰手冊第三版 (碁峰)
- jQuery 最強圖解實戰講座 (旗標)
- JavaScript 函數活用範例速查辭典 (博碩)
- Learning jQuery3 5th Edition (Packt)
- JavaScript & jQuery-The Missing Manual (O'Reilly)
jQuery 的 API 參考 :
# https://api.jquery.com/
jQuery 的語法很簡單, 就是先用工廠函數 $() 以選擇器取得元素的 jQuery 物件 (集合), 再呼叫其物件方法 :
$(選擇器).方法(參數1, 參數2, ....)
選擇器語法是在 CSS 選擇器基礎上再添加一些 jQuery 自己的選擇器, 因此用法基本上與 CSS 選擇器相同, 其次, 有些方法的參數可能是個函式.
選擇器語法是在 CSS 選擇器基礎上再添加一些 jQuery 自己的選擇器, 因此用法基本上與 CSS 選擇器相同, 其次, 有些方法的參數可能是個函式.
以下是 jQuery 的常用技法, 大多是 jQuery 物件的方法或函數. jQuery 的方法與函數在使用上與 Javascript 最大的不同有如下兩點 :
1. 函式串接 (chaining functions 或 method chains) :
jQuery 物件的方法或 jQuery 頂層函式都可以用點運算符連續串接, 例如 :
1. 函式串接 (chaining functions 或 method chains) :
jQuery 物件的方法或 jQuery 頂層函式都可以用點運算符連續串接, 例如 :
$("#img1").width(200).height(300);
2. 自動迴圈 (automatic loops) :
如果使用 Javascript 操作 DOM 來處理頁面元素的屬性與行為, 例如隱藏頁面中的所有圖片 :
$("img").hide();
選擇器 $("img") 選取了頁面中全部圖片, 如果用 Javascript 去設定這些圖片的樣式來隱藏勢必需要使用迴圈, 呼叫 hide() 卻只需要一個指令, 事實上 jQuery 是在背後自動用迴圈處理掉了.
一. 常用選擇器 :
jQuery 採用 CSS 的選擇器語法來取得網頁元素, 以下為最常用的基本選擇器用法 :
1. id 選擇器 (# id selector) :
使用 # 與元素的 id 屬性 (具有唯一識別性) 來取得網頁元素, 語法為 $("#id"), 例如下列 id=mydiv 的 div 元素 :
<div id="mydiv"></div>
則 $("#mydiv") 將傳回此 div 元素的 jQuery 物件 (應該是唯一) :
var mydiv=$("#mydiv");
2. 類別選擇器 (. class selector) :
類別選擇器使用 "." 與元素的樣式類別來取得網頁元素, 語法為 $(".樣式類別名稱"), 由於網頁中可能有多個元素套用相同樣式類別, 因此它會傳回一個 jQuery 物件集合 (collection), 例如 :
<ul>
<li class="myclass">A</li>
<li class="myclass">B</li>
<li class="myclass">C</li>
</ul>
則 $(.myclass) 將傳回一個 jQuery 物件集合, 類似陣列, 可用 length 屬性取得其長度, 也可用 each() 工具函數拜訪集合之元素 :
var myclass=$(".myclass");
console.log(myclass.length); //輸出 3
myclass.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
此處回呼函數內的 this 為配選取之 DOM 元素, 不是被選取的 jQuery 物件, 必須傳入 $() 才是.
3. 元素選擇器 (element selector) :
元素選擇器以元素的標籤篩選網頁中的元素, 語法為 $("標籤"), 例如下列選項清單中的 li 元素 :
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
由於指定的標籤在網頁中可能有多個, 因此也是傳回一個 jQuery 物件集合 :
var myli=$("li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
4. 後代選擇器 (descendant selectors) :
此選擇器可篩選某元素的所有後代元素, 可精確選取所要的元素, 語法為 $("父元素選擇器 後代元素選擇器"), 即中間空一格, 例如下面的 li 是 div 的後代元素 :
<div id="mydiv">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>
如果只用元素選擇器 $("li") 將選取頁面上的全部 li 元素, 而使用 $(#myul li) 才能精確選取這三個 li 元素.
var myli=$("#mydiv li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
5. 子元素選擇器 (child selector) :
此選擇器用來選取子元素 (即直接後代, 不含孫元素), 語法是 $("父元素 > 子元素"), 例如下面的 li 是 ul 元素的子元素 :
<ul id="myul">
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
先用 id 選擇器選取父元素 ul, 再用子元素選擇器選取子元素 :
var myli=$("#myul > li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
6. 次元素選擇器 (adjacent selector) :
此選擇器選取緊鄰的下一個元素, 語法為 $("前元素 + 次元素"), 傳回值為一個 jQuery 物件, 不是物件集合, 例如下列網頁 :
<h3>A</h1>
<div>B</div>
<div>C</div>
則 $("h3 + div") 會選取 h3 元素後面跟著的第一個 div 元素 :
var next=$("h3 + div");
console.log(next.length); //輸出 1
console.log(next.text()); //輸出 B
7. 所有次元素選擇器 (following-all-siblings selector) :
此選擇器選取所有後面的兄弟元素 (siblings), 語法為 $("前元素 ~ 次元素"), 傳回值為 jQuery 物件集合, 例如下列網頁 :
<h3>A</h1>
<div>B</div>
<div>C</div>
則 $("h3 ~ div") 會選取 h3 元素後面跟著所有同層元素 :
var nextALL=$("h3 ~ div");
console.log(nextALL.length); //輸出 2
nextALL.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 B, 1 C
});
8. 屬性選擇器 (attribute selector) :
此選擇器用來選取屬性值符合特定條件之元素 :
其中 [attr*=foo] 與 [attr~=foo] 的差異在於 [attr*=foo] 會包含子字串; 而 [attr~=foo] 則不包含, 在屬性值有多個以空格隔開情形就能看出差異, 例如 class="foo foo1" 與 class="foofoo1" 若用 [attr*=foo] 兩者都會被選到, 但若用 [attr~=foo] 則只有前者會被選到, 因為後者是在子字串中找到 foo, 而 [attr~=foo] 不含子字串, 它是要在空格隔開中全等才符合.
9. 表單選擇器 (form selector) :
此選擇器用於選取表單元素 (form) 內部的 input, select, button, 以及 textarea 等元素, 均以冒號開頭, 為了便於閱讀, 除了 :input 選擇器外, 其他選擇器最好加上標籤名稱, 例如用 input:text, input:radio 或 select:selected 等等 :
二. 常用 jQuery 物件方法 :
1. 操作網頁元素之隱藏與顯示 :
呼叫 hide() 方法可隱藏網頁元素, 而 show() 則可使其顯示, 例如 :
$("#element").hide();
$("#element").show();
呼叫 hide() 時此函數會先將該元素的 display 樣式值 (inline 或 block 等) 記下來, 然後再將該元素的 display 樣式設為 none, 這與呼叫 $("#element").css("display", "none") 的效果一樣; 而呼叫 show() 時此函數會將原先記下來的 display 樣式值恢復 (例如 inline 或 block).
2. 操作網頁元素的內容 :
所謂網頁元素的內容是指有開始與結束標籤的元素而言, 其內容即夾在兩者之間的部分 (會顯示在瀏覽器上), 也就是 DOM 物件中 innerHTML 屬性之值, 例如下面的 p 元素 :
<p id="para">Hello World</p>
呼叫 html() 即可取得 p 元素的 innerHTML 屬性值 "Hello World" :
$("#papa").html(); //取得網頁元素的內容
如果傳參數 (字串) 進去, 那就是設定 (修改) p 元素的內容 :
$("#papa").html("<b>How are you?</b>"); ////修改網頁元素的內容
另外還有一個 text() 函數可用來存取元素的純文字內容 (去除 HTML 標籤的部分, 包含跳行等字元), 也就是 DOM 物件中的 innerText 屬性之值 :
$("#papa").text(); //取得網頁元素的 innerText 內容
$("#papa").text("How are you?"); //設定網頁元素的 innerText 內容
如果要將某個元素的 innerHTML 內容清空, 可用 empty() 方法達成, 例如上面 id=para 的 p 元素 :
$("#para").empty();
這樣會使該 p 元素內容變空白 (但 p 標籤仍在) :
<p id="para"></p>
如果要將某個元素以新的內容或新的標籤取代, 可呼叫 replaceWith(), 例如要將上面的 p 元素內容改為 "How are you" 可以這麼做 :
$("#para").replaceWith("<p id="para">How are you</p>");
注意, 傳入的參數會完全取代該元素 (包含標籤), 因此若只傳入內容 $("#para").replaceWith("How are you"), 則連 p 元素的開始與結束標籤都不見了, 只剩下 "How are you", 因此 replaceWith() 也可以用來更換元素, 例如將 p 元素換成 div 元素 :
$("#para").replaceWith("<div id="para">How are you</div>");
3. 操作網頁元素的屬性 :
呼叫 attr() 方法可操作元素的屬性, 只傳入一個參數為 getter; 傳入兩個參數為 setter :
obj.attr("屬性名稱") : 傳回屬性值
obj.attr("屬性名稱", "屬性值") : 設定屬性值
例如網頁元素 p :
<p id="para" style="color: blue;">Hello World</p>
var style=$("#para").attr("style"); //傳回 "color: blue;"
$("#para").attr("style", "color: green;"); //設定前景色為 green
attr() 方法很廣用, 例如可用來操作樣式屬性 style 與類別 class.
4. 操作網頁元素的尺寸 :
呼叫 width() 與 height() 可存取網頁元素的尺寸, 語法如下 :
obj.width() : 傳回元素寬度 (數值 : 單位 px)
obj.width(寬度) : 設定元素寬度 (數值或帶 px 單位字串)
obj.height() : 傳回元素長度 (數值 : 單位 px)
obj.height(長度) : 設定元素長度 (數值或帶 px 單位字串)
注意, width() 與 height() 的傳回值是不附單位的數值 (預設單位是 px), 這與呼叫 css("width") 或 css("heigght") 不同, 後者是有帶單位的. 例如下面的按鈕 :
<button id="btn">OK</button>
用 css() 與 width() 取得的預設按鈕寬度不同 :
console.log($("#btn").css("width")); //輸出 35.2557px (帶單位且為外尺寸)
console.log($("#btn").width()); //輸出 19.25947 (不帶單位且為內尺寸)
但若經過設定, 取回的值就一樣了 :
<button id="btn1">OK</button><br>
<button id="btn2">OK</button>
$("#btn1").css("width","100px");
$("#btn2").width("100px");
console.log($("#btn1").css("width")); //傳回 100px
console.log($("#btn2").width()); //傳回 100
但用 width() 設定的寬度會比較大一些.
若要從 css() 的帶單位傳回值取出數值, 可用 Javascript 的 parseInt() 函數 :
console.log(parseInt($("#btn1").css("width"))); //傳回 100
5. 操作網頁元素的樣式 :
呼叫 css() 方法可操作元素的樣式, 只傳入一個參數為 getter; 傳入兩個參數為 setter :
obj.css("樣式名稱") : 傳回樣式內容
obj.css("樣式名稱", "樣式內容") : 設定樣式內容
傳入雜湊物件 (鍵值對) 則可一次設定多個樣式 :
obj.css({"樣式名稱1":"樣式內容1", "樣式名稱2":"樣式內容2"} ...) : 設定多個樣式內容
例如網頁元素 p :
<p id="para" style="color: blue;">Hello World</p>
var style=$("#para").css("color"); //傳回 "blue"
$("#para").css("color", "green"); //設定前景色為 "green"
$("#para").css({"color":"green", "font-color":"#0000ff"}); //設定多個樣式
注意, css() 傳回的是 style 屬性中完整的樣式設定, 例如 :
<p id="foo" style="width:200px;color=blue">A</p>
$("#foo").css("width") 傳回值是帶單位的 "200px", 而 $("#foo").width() 傳回的是不帶單位的 "200".
6. 操作網頁元素的樣式類別 :
呼叫 addClass() 添加樣式 (原有樣式仍在但可能被覆蓋); 呼叫 removeClass() 則移除指定樣式 :
obj.addClass("樣式類別名稱"); //添加樣式類別
ㄌobj.removeClass("樣式類別名稱"); //移除已存在之樣式類別
例如網頁元素 p :
<p id="para">Hello World</p>
可用 $("#para").addClass("p1") 添加下列樣式類別 :
.p1 {color: blue; font-style: italic}
呼叫 $("#para").removeClass("p1") 則可移除已有之樣式類別 p1.
如果要直接覆蓋已有之全部樣式類別可以呼叫 attr() :
obj.attr("class", "樣式類別名稱"); //設定物件之樣式類別 (完全覆蓋)
判斷物件是否含有指定樣式類別可呼叫 hasClass() 方法 :
obj.hasClass("樣式類別名稱"); //若含有指定之樣式類別傳回 true, 否則傳回 false
這可用來切換 (toggle) 是否要套用某個樣式類別 (如果沒有就套用, 已有就移除). 不過 toggle 的功能 jQuery 已經有一個現成的方法 toggleClass() 可用來切換類別是否套用 :
obj.toggleClass("樣式類別名稱"); //若元素無此類別樣式就套用, 若已套用就移除
也可以傳入第二個參數 switch (布林判斷式, 例如 a == 5) 來決定是否套用 :
obj.toggleClass("樣式類別名稱", switch); //若 switch=true 就套用樣式類別, 否則就移除
7. 操作表單元素的內容 :
呼叫 val() 方法可以存取文字類表單元件例如 input 文字欄位 (type=text), 密碼欄位 (type=password), 以及文字區域 textarea 等 :
obj.val(); //傳回物件之 value 屬性值
obj.val("請輸入 email"); //設定物件之 value 屬性值
但是對於選項類元件則需配合選擇器才能取得被選擇之選項值.
對於 radio 或 checkbox 元件, 要取得被選取的選項值 (radio) 或值陣列 (checkbox) 除了使用 $("[name=元素名稱]") 外還必須再加上屬性過濾選擇器 :checked 才行, 如果只用 $("[name=元素名稱]"), 則呼叫 val() 會固定傳回第一個選項之值 (不管有沒有選都一樣), 正確的用法如下 :
$("[name=元素名稱]:radio:checked").val(); //取得被選取之 radio 選項值 (單選)
對於可複選的核取方塊 checkbox, 即使選擇器使用 $("[name=元素名稱]:checkbox:checked"), 呼叫 val() 仍然只會傳回第一個選項值, 因為它的傳回值是一個陣列, 必須使用一個空陣列並透過 each 迴圈來逐一將被選取選項值放入空陣列中以取得被選取值陣列, 例如 :
var selected=[];
$("[name=元素名稱]:checkbox:checked").each(function(){
selected.push($(this).val());
})
對於單選的下拉式選單 select (無 multiple 屬性者), 直接呼叫 val() 即可取得被選取之選項值, 若都未選傳回 null; 對於可複選的下拉式選單 (有 multiple 屬性者), 取得被選取選項值的做法與 checkbox 類似, 以過濾選擇器 "[name=元素名稱]:selected" 取得物件後, 呼叫 each() 拜訪傳回值陣列, 並將其存入空陣列之中 :
var selected=[];
$("[name=元素名稱]:selected").each(function(){
selected.push($(this).val());
})
8. 事件綁定與處理 :
jQuery 支援滑鼠, 鍵盤, 以及表單等事件, 在 v1.7 版後它棄用 bind() 與 live() 等方法, 改用 on() 的方法來綁定事件與其事件處理函式, 其 API 有如下兩種 :
obj.on(eventType [, selector] [, data], function(e) {})
obj.on(eventsHash [, selector] [, data])
第一參數是要綁定的事件類型字串或事件雜湊, 前者可以是單一的事件類型字串例如 "click", 也可以是以空格隔開的多個事件類型字串例如 "click mouseover keydown" (多個事件綁定一個事件處理函式). 第一參數也可以是以事件類型與其處理函式組成的鍵值對 (hash), 可用來一次綁定多個事件.
備選之第二參數 selector 是事件委託 (event delegation) 的選擇器字串, 用來過濾被選取元素中觸發事件之子節點, 亦即子節點觸發事件, 但是卻在父元素綁定事件處理器. 事件委託給父元素在 以 Ajax 載入子節點操作時很好用, 因為要觸發事件之子節點尚未存在, 只好將事件處理函式綁定給父元素.
備選之第三參數是要傳給事件物件 e 的參數 (鍵值對), 可在事件處理函式中以 e.data 第四參數為必要之事件處理函數. 如果不需要第二與第三參數也不需要傳入兩個 null, 直接略過即可 (jQuery 會自動處理).
jQuery 支援之事件類型如下 :
其中最常用的是按鈕的 click 事件, 例如下列按鈕 :
<button id="btn">按我</button>
呼叫 button 元素物件的 on() 方法為其綁定 click 事件 :
$("#btn").on("click", function(e){
alert("你按了按鈕!");
});
可以多個事件綁定一個事件處理函式, 各事件類型字串以空格隔開, 例如 :
$("#btn").on("click mouseover", function(e){
alert("你按了按鈕!");
});
傳入第二參數 data 可將資料以鍵值對 (物件) 傳遞給事件物件 e, 在回呼函數中可用 e.data.屬性名稱取值, 例如 :
$("#btn").on("click", {"name":"Tony"}, function(e){
alert(e.data.name + " 按了按鈕!"); //顯示 "Tony 按了按鈕"
})
對於這些事件, jQuery 物件也有捷徑方法可以直接綁定事件處理函式 (語法較簡短), 例如 :
$("#btn").click(function(e){
alert("你按了按鈕!");
})
捷徑方法也可以傳遞 data 參數 (備選第一參數) :
$("#btn").click({"name":"Tony"}, function(e){
alert(e.data.name + " 按了按鈕!"); //顯示 "Tony 按了按鈕"
})
如果要替元素綁定多個事件, 可以用鏈式呼叫 on(), 例如 :
$("#btn").on("click", function(e){
console.log("按了按鈕!");
}).on("mouseover", function(e){
console.log("滑鼠滑過按鈕!");
});
也可以用事件雜湊來一次綁定多個事件 (為了可讀性可將事件處理函式命名), 例如 :
var eh1=function(e){console.log("按了按鈕!");};
var eh2=function(e){console.log("滑過按鈕!");};
$("#btn").on({click: eh1, mouseover: eh2}); // 鍵用字串 "click": eh1 也可以
傳遞資料的範例如下 (注意, data 是放在第二參數) :
var eh1=function(e){console.log(e.data.name + "按了按鈕!");};
var eh2=function(e){console.log("滑過按鈕!");};
$("#btn").on({click: eh1, mouseover: eh2},{"name":"Tony"});
事件物件 e 常用的屬性除 data 外還有表示滑鼠位置的 pageX 與 pageY; 常用方法有停止元素預設動作 (例如表單元素 form 之提交, 超連結元素 a 的重導向, 或核取方塊狀態之變化等) 的 preventDefault() 與停止事件沿 DOM 樹向上傳遞的 stopPropagation(). 典型的範例是以超連結當按鈕使用時, 必須於事件處理函式結尾以 return false 避免除新載入頁面, 這與連續呼叫 preventDefault() 與 stopPropagation() 效果相同.
有些情況需要取消事件綁定, 這可用呼叫 off() 達成, 其 API 如下 :
obj.off(eventType [, selector] [, handler])
obj.off(eventsHash [, selector]])
例如 :
$("#btn").off("click mouseover");
9. 用 Ajax 取得遠端網頁或資料 :
Ajax 必須有後端伺服器配合才行, 在本機無法運作. jQuery 的 Ajax 函式與方法主要是由頂層函數 $.ajax(), 頂層捷徑函數 $.get(), $.post 與 $.getJSON(), 以及 jQuery 物件方法 obj.load() 構成, 其中 $.ajax() 是最底層函數, 其它函數與方法均以 $.ajax() 為基礎.
呼叫 $.ajax() 時必須傳入一個設定物件, 主要屬性與方法如下 :
伺服端的 Ajax 回應資料會傳入 success 屬性值的回呼函數參數 data 中, 例如載入遠端伺服器上的 HTML 檔 test.htm 時, 可將回應網頁從回呼函數參數 data 中取出後用 html() 方法填入 id=result 的指定元素內容中 :
$.ajax({
type: "GET",
url: "test.htm",
dataType: "html",
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
動態網頁需要傳遞參數給伺服端的程式處理, 傳遞參數通常用 POST 方式將參數放在 HTTP 的 body 中傳送, 也可以用 GET 方式放在 HTTP 標頭中傳遞. 參數可以附在 url 屬性後面以查詢字串方式傳遞; 也可以用鍵值對方式放在 data 屬性中傳遞, 後端程式擷取 HTTP 參數的方式以 PHP 而言可用 $_GET[] 或 $_POST[] 取得, 但要視參數是放在 url 或 data 屬性而定 :
$.ajax({
type: "POST",
url: "test.php",
dataType: "html",
data: {user: "tony", pwd: 123},
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
回應 HTML 資料的後端 PHP 範例如下 (注意 header) :
<?php
header("Content-Type: text/html; charset: utf-8");
echo "<p>get :user=".$_GET['user'].", pwd=".$_GET['pwd']."</p>".
"<p>post : user=".$_POST['user'].", pwd=".$_POST['pwd']."</p>".
"<p>post : user=".$_REQUEST['user'].", pwd=".$_REQUEST['pwd']."</p>".
"<p style='font-weight:bold;'>Hello World!</p>".
"<p id='normal'>Hello World!</p>";
?>
實際應用上是將表單元素之輸入值提交給後端伺服器, 表單元素 form 的 jQuery 物件有一個 serialize() 方法可將表單內有 name 屬性的元件輸入值轉成查詢字串, 例如下列登入表單 :
<form id="login_form">
<label for="user">帳號 : </label>
<input type="text" id="user" name="user"><br>
<label for="pwd">密碼 : </label>
<input type="text" id="pwd" name="pwd">
<button id="login">登入</button>
</form>
可用 $("#login_form").serialize() 將表單內的輸入元件值轉成 "user=tony&pwd=12345" 的查詢字串傳遞到後端, 例如 :
$.ajax({
type: "POST",
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
除了 $.ajax() 外 jQuery 還提供較高階的捷徑函數, 較常用的是這三個 :
$.get({
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
}
});
呼叫 $.post() 則以 POST 方式發出請求 :
$.post({
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
}
});
若僅僅是查詢資料, 伺服端更精簡的方式是直接回應 JSON 資料再填入網頁內, 例如 :
{"user":"tony","pwd":"123"}
一. 常用選擇器 :
jQuery 採用 CSS 的選擇器語法來取得網頁元素, 以下為最常用的基本選擇器用法 :
1. id 選擇器 (# id selector) :
使用 # 與元素的 id 屬性 (具有唯一識別性) 來取得網頁元素, 語法為 $("#id"), 例如下列 id=mydiv 的 div 元素 :
<div id="mydiv"></div>
則 $("#mydiv") 將傳回此 div 元素的 jQuery 物件 (應該是唯一) :
var mydiv=$("#mydiv");
2. 類別選擇器 (. class selector) :
類別選擇器使用 "." 與元素的樣式類別來取得網頁元素, 語法為 $(".樣式類別名稱"), 由於網頁中可能有多個元素套用相同樣式類別, 因此它會傳回一個 jQuery 物件集合 (collection), 例如 :
<ul>
<li class="myclass">A</li>
<li class="myclass">B</li>
<li class="myclass">C</li>
</ul>
則 $(.myclass) 將傳回一個 jQuery 物件集合, 類似陣列, 可用 length 屬性取得其長度, 也可用 each() 工具函數拜訪集合之元素 :
var myclass=$(".myclass");
console.log(myclass.length); //輸出 3
myclass.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
此處回呼函數內的 this 為配選取之 DOM 元素, 不是被選取的 jQuery 物件, 必須傳入 $() 才是.
3. 元素選擇器 (element selector) :
元素選擇器以元素的標籤篩選網頁中的元素, 語法為 $("標籤"), 例如下列選項清單中的 li 元素 :
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
由於指定的標籤在網頁中可能有多個, 因此也是傳回一個 jQuery 物件集合 :
var myli=$("li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
4. 後代選擇器 (descendant selectors) :
此選擇器可篩選某元素的所有後代元素, 可精確選取所要的元素, 語法為 $("父元素選擇器 後代元素選擇器"), 即中間空一格, 例如下面的 li 是 div 的後代元素 :
<div id="mydiv">
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>
如果只用元素選擇器 $("li") 將選取頁面上的全部 li 元素, 而使用 $(#myul li) 才能精確選取這三個 li 元素.
var myli=$("#mydiv li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
5. 子元素選擇器 (child selector) :
此選擇器用來選取子元素 (即直接後代, 不含孫元素), 語法是 $("父元素 > 子元素"), 例如下面的 li 是 ul 元素的子元素 :
<ul id="myul">
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
先用 id 選擇器選取父元素 ul, 再用子元素選擇器選取子元素 :
var myli=$("#myul > li");
console.log(myli.length); //輸出 3
myli.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 A, 1 B, 2 C
});
6. 次元素選擇器 (adjacent selector) :
此選擇器選取緊鄰的下一個元素, 語法為 $("前元素 + 次元素"), 傳回值為一個 jQuery 物件, 不是物件集合, 例如下列網頁 :
<h3>A</h1>
<div>B</div>
<div>C</div>
則 $("h3 + div") 會選取 h3 元素後面跟著的第一個 div 元素 :
var next=$("h3 + div");
console.log(next.length); //輸出 1
console.log(next.text()); //輸出 B
7. 所有次元素選擇器 (following-all-siblings selector) :
此選擇器選取所有後面的兄弟元素 (siblings), 語法為 $("前元素 ~ 次元素"), 傳回值為 jQuery 物件集合, 例如下列網頁 :
<h3>A</h1>
<div>B</div>
<div>C</div>
則 $("h3 ~ div") 會選取 h3 元素後面跟著所有同層元素 :
var nextALL=$("h3 ~ div");
console.log(nextALL.length); //輸出 2
nextALL.each(function(idx){
console.log(idx + " " + $(this).text()); //分別輸出 0 B, 1 C
});
8. 屬性選擇器 (attribute selector) :
此選擇器用來選取屬性值符合特定條件之元素 :
屬性選擇器 | 說明 |
[attr] | 選取全部具有 attr 屬性的元素, 例如 [class] 選取所有含 class 屬性之元素 |
[attr=foo] | 選取 attr 屬性全等於 foo 之全部元素, 例如 [name=fruits] |
[attr!=foo] | 選取 attr 屬性不等於 foo 之全部元素, 例如 [name!=fruits] |
[attr^=foo] | 選取 attr 屬性以 foo 開頭之全部元素, 例如 [href^=https] |
[attr$=foo] | 選取 attr 屬性以 foo 結束之全部元素, 例如 [href$=tw] |
[attr*=foo] | 選取 attr 屬性包含 foo 之全部元素 (含子字串), 例如 [href*=org] |
[attr~=foo] | 選取 attr 屬性 (以空格隔開) 包含 foo 之全部元素 (不含子字串), 例如 [class~=foo] |
[attr|=foo] | 選取 attr 屬性全等於 foo 或以 foo 開頭之全部元素, 例如 [class|=foo] |
其中 [attr*=foo] 與 [attr~=foo] 的差異在於 [attr*=foo] 會包含子字串; 而 [attr~=foo] 則不包含, 在屬性值有多個以空格隔開情形就能看出差異, 例如 class="foo foo1" 與 class="foofoo1" 若用 [attr*=foo] 兩者都會被選到, 但若用 [attr~=foo] 則只有前者會被選到, 因為後者是在子字串中找到 foo, 而 [attr~=foo] 不含子字串, 它是要在空格隔開中全等才符合.
9. 表單選擇器 (form selector) :
此選擇器用於選取表單元素 (form) 內部的 input, select, button, 以及 textarea 等元素, 均以冒號開頭, 為了便於閱讀, 除了 :input 選擇器外, 其他選擇器最好加上標籤名稱, 例如用 input:text, input:radio 或 select:selected 等等 :
表單選擇器 | 說明 |
:input | 選取所有表單元素, 包含 input, select, textarea, 與 button |
:text | 選取所有文字欄位元素, 即 <input type="text"> |
:password | 選取所有密碼欄位元素, 即 <input type="password"> |
:radio | 選取所有單選圓鈕元素, 即 <input type="radio"> |
:checkbox | 選取所有核取方塊元素, 即 <input type="checkbox"> |
:submit | 選取所有提交按鈕元素, 即 <input type="text"> 與 <button type="button"> |
:image | 選取所有提交圖片按鈕元素, 即 <input type="image"> |
:reset | 選取所有重設按鈕元素, 即 <input type="reset"> 與 <button type="reset"> |
:button | 選取所有按鈕元素, 即 <input type="button"> 與 <button type="button"> |
:file | 選取所有檔案上傳欄位元素, 即 <input type="file"> |
:enabled | 選取所有啟用 (可與使用者互動) 之表單元素, 即無 disabled 屬性之表單元素 |
:disabled | 選取所有停用 (無法與使用者互動) 之表單元素, 即有 disabled 屬性之表單元素 |
:checked | 選取所有被核取之表單元素, 包含被核取之 checkbox 與 radio 元素 |
:selected | 選取所有被選擇之 select 元素中的 option 元素 |
二. 常用 jQuery 物件方法 :
1. 操作網頁元素之隱藏與顯示 :
呼叫 hide() 方法可隱藏網頁元素, 而 show() 則可使其顯示, 例如 :
$("#element").hide();
$("#element").show();
呼叫 hide() 時此函數會先將該元素的 display 樣式值 (inline 或 block 等) 記下來, 然後再將該元素的 display 樣式設為 none, 這與呼叫 $("#element").css("display", "none") 的效果一樣; 而呼叫 show() 時此函數會將原先記下來的 display 樣式值恢復 (例如 inline 或 block).
2. 操作網頁元素的內容 :
所謂網頁元素的內容是指有開始與結束標籤的元素而言, 其內容即夾在兩者之間的部分 (會顯示在瀏覽器上), 也就是 DOM 物件中 innerHTML 屬性之值, 例如下面的 p 元素 :
<p id="para">Hello World</p>
呼叫 html() 即可取得 p 元素的 innerHTML 屬性值 "Hello World" :
$("#papa").html(); //取得網頁元素的內容
如果傳參數 (字串) 進去, 那就是設定 (修改) p 元素的內容 :
$("#papa").html("<b>How are you?</b>"); ////修改網頁元素的內容
另外還有一個 text() 函數可用來存取元素的純文字內容 (去除 HTML 標籤的部分, 包含跳行等字元), 也就是 DOM 物件中的 innerText 屬性之值 :
$("#papa").text(); //取得網頁元素的 innerText 內容
$("#papa").text("How are you?"); //設定網頁元素的 innerText 內容
如果要將某個元素的 innerHTML 內容清空, 可用 empty() 方法達成, 例如上面 id=para 的 p 元素 :
$("#para").empty();
這樣會使該 p 元素內容變空白 (但 p 標籤仍在) :
<p id="para"></p>
如果要將某個元素以新的內容或新的標籤取代, 可呼叫 replaceWith(), 例如要將上面的 p 元素內容改為 "How are you" 可以這麼做 :
$("#para").replaceWith("<p id="para">How are you</p>");
注意, 傳入的參數會完全取代該元素 (包含標籤), 因此若只傳入內容 $("#para").replaceWith("How are you"), 則連 p 元素的開始與結束標籤都不見了, 只剩下 "How are you", 因此 replaceWith() 也可以用來更換元素, 例如將 p 元素換成 div 元素 :
$("#para").replaceWith("<div id="para">How are you</div>");
3. 操作網頁元素的屬性 :
呼叫 attr() 方法可操作元素的屬性, 只傳入一個參數為 getter; 傳入兩個參數為 setter :
obj.attr("屬性名稱") : 傳回屬性值
obj.attr("屬性名稱", "屬性值") : 設定屬性值
例如網頁元素 p :
<p id="para" style="color: blue;">Hello World</p>
var style=$("#para").attr("style"); //傳回 "color: blue;"
$("#para").attr("style", "color: green;"); //設定前景色為 green
attr() 方法很廣用, 例如可用來操作樣式屬性 style 與類別 class.
4. 操作網頁元素的尺寸 :
呼叫 width() 與 height() 可存取網頁元素的尺寸, 語法如下 :
obj.width() : 傳回元素寬度 (數值 : 單位 px)
obj.width(寬度) : 設定元素寬度 (數值或帶 px 單位字串)
obj.height() : 傳回元素長度 (數值 : 單位 px)
obj.height(長度) : 設定元素長度 (數值或帶 px 單位字串)
注意, width() 與 height() 的傳回值是不附單位的數值 (預設單位是 px), 這與呼叫 css("width") 或 css("heigght") 不同, 後者是有帶單位的. 例如下面的按鈕 :
<button id="btn">OK</button>
用 css() 與 width() 取得的預設按鈕寬度不同 :
console.log($("#btn").css("width")); //輸出 35.2557px (帶單位且為外尺寸)
console.log($("#btn").width()); //輸出 19.25947 (不帶單位且為內尺寸)
但若經過設定, 取回的值就一樣了 :
<button id="btn1">OK</button><br>
<button id="btn2">OK</button>
$("#btn1").css("width","100px");
$("#btn2").width("100px");
console.log($("#btn1").css("width")); //傳回 100px
console.log($("#btn2").width()); //傳回 100
但用 width() 設定的寬度會比較大一些.
若要從 css() 的帶單位傳回值取出數值, 可用 Javascript 的 parseInt() 函數 :
console.log(parseInt($("#btn1").css("width"))); //傳回 100
5. 操作網頁元素的樣式 :
呼叫 css() 方法可操作元素的樣式, 只傳入一個參數為 getter; 傳入兩個參數為 setter :
obj.css("樣式名稱") : 傳回樣式內容
obj.css("樣式名稱", "樣式內容") : 設定樣式內容
傳入雜湊物件 (鍵值對) 則可一次設定多個樣式 :
obj.css({"樣式名稱1":"樣式內容1", "樣式名稱2":"樣式內容2"} ...) : 設定多個樣式內容
例如網頁元素 p :
<p id="para" style="color: blue;">Hello World</p>
var style=$("#para").css("color"); //傳回 "blue"
$("#para").css("color", "green"); //設定前景色為 "green"
$("#para").css({"color":"green", "font-color":"#0000ff"}); //設定多個樣式
注意, css() 傳回的是 style 屬性中完整的樣式設定, 例如 :
<p id="foo" style="width:200px;color=blue">A</p>
$("#foo").css("width") 傳回值是帶單位的 "200px", 而 $("#foo").width() 傳回的是不帶單位的 "200".
6. 操作網頁元素的樣式類別 :
呼叫 addClass() 添加樣式 (原有樣式仍在但可能被覆蓋); 呼叫 removeClass() 則移除指定樣式 :
obj.addClass("樣式類別名稱"); //添加樣式類別
ㄌobj.removeClass("樣式類別名稱"); //移除已存在之樣式類別
例如網頁元素 p :
<p id="para">Hello World</p>
可用 $("#para").addClass("p1") 添加下列樣式類別 :
.p1 {color: blue; font-style: italic}
呼叫 $("#para").removeClass("p1") 則可移除已有之樣式類別 p1.
如果要直接覆蓋已有之全部樣式類別可以呼叫 attr() :
obj.attr("class", "樣式類別名稱"); //設定物件之樣式類別 (完全覆蓋)
判斷物件是否含有指定樣式類別可呼叫 hasClass() 方法 :
obj.hasClass("樣式類別名稱"); //若含有指定之樣式類別傳回 true, 否則傳回 false
這可用來切換 (toggle) 是否要套用某個樣式類別 (如果沒有就套用, 已有就移除). 不過 toggle 的功能 jQuery 已經有一個現成的方法 toggleClass() 可用來切換類別是否套用 :
obj.toggleClass("樣式類別名稱"); //若元素無此類別樣式就套用, 若已套用就移除
也可以傳入第二個參數 switch (布林判斷式, 例如 a == 5) 來決定是否套用 :
obj.toggleClass("樣式類別名稱", switch); //若 switch=true 就套用樣式類別, 否則就移除
7. 操作表單元素的內容 :
呼叫 val() 方法可以存取文字類表單元件例如 input 文字欄位 (type=text), 密碼欄位 (type=password), 以及文字區域 textarea 等 :
obj.val(); //傳回物件之 value 屬性值
obj.val("請輸入 email"); //設定物件之 value 屬性值
但是對於選項類元件則需配合選擇器才能取得被選擇之選項值.
對於 radio 或 checkbox 元件, 要取得被選取的選項值 (radio) 或值陣列 (checkbox) 除了使用 $("[name=元素名稱]") 外還必須再加上屬性過濾選擇器 :checked 才行, 如果只用 $("[name=元素名稱]"), 則呼叫 val() 會固定傳回第一個選項之值 (不管有沒有選都一樣), 正確的用法如下 :
$("[name=元素名稱]:radio:checked").val(); //取得被選取之 radio 選項值 (單選)
對於可複選的核取方塊 checkbox, 即使選擇器使用 $("[name=元素名稱]:checkbox:checked"), 呼叫 val() 仍然只會傳回第一個選項值, 因為它的傳回值是一個陣列, 必須使用一個空陣列並透過 each 迴圈來逐一將被選取選項值放入空陣列中以取得被選取值陣列, 例如 :
var selected=[];
$("[name=元素名稱]:checkbox:checked").each(function(){
selected.push($(this).val());
})
對於單選的下拉式選單 select (無 multiple 屬性者), 直接呼叫 val() 即可取得被選取之選項值, 若都未選傳回 null; 對於可複選的下拉式選單 (有 multiple 屬性者), 取得被選取選項值的做法與 checkbox 類似, 以過濾選擇器 "[name=元素名稱]:selected" 取得物件後, 呼叫 each() 拜訪傳回值陣列, 並將其存入空陣列之中 :
var selected=[];
$("[name=元素名稱]:selected").each(function(){
selected.push($(this).val());
})
8. 事件綁定與處理 :
jQuery 支援滑鼠, 鍵盤, 以及表單等事件, 在 v1.7 版後它棄用 bind() 與 live() 等方法, 改用 on() 的方法來綁定事件與其事件處理函式, 其 API 有如下兩種 :
obj.on(eventType [, selector] [, data], function(e) {})
obj.on(eventsHash [, selector] [, data])
第一參數是要綁定的事件類型字串或事件雜湊, 前者可以是單一的事件類型字串例如 "click", 也可以是以空格隔開的多個事件類型字串例如 "click mouseover keydown" (多個事件綁定一個事件處理函式). 第一參數也可以是以事件類型與其處理函式組成的鍵值對 (hash), 可用來一次綁定多個事件.
備選之第二參數 selector 是事件委託 (event delegation) 的選擇器字串, 用來過濾被選取元素中觸發事件之子節點, 亦即子節點觸發事件, 但是卻在父元素綁定事件處理器. 事件委託給父元素在 以 Ajax 載入子節點操作時很好用, 因為要觸發事件之子節點尚未存在, 只好將事件處理函式綁定給父元素.
備選之第三參數是要傳給事件物件 e 的參數 (鍵值對), 可在事件處理函式中以 e.data 第四參數為必要之事件處理函數. 如果不需要第二與第三參數也不需要傳入兩個 null, 直接略過即可 (jQuery 會自動處理).
jQuery 支援之事件類型如下 :
滑鼠事件 | 說明 |
click | 點擊元素 |
dbclick | 雙擊元素 |
mouseenter | 滑鼠游標滑入元素 |
mouseover | 滑鼠游標滑入元素 |
mouseleave | 滑鼠游標移出元素 |
mouserout | 滑鼠游標移出元素 |
mousemove | 滑鼠游標在元素上移動 |
mouseup | 放開滑鼠左鍵 |
mousedownn | 按下滑鼠左鍵 |
鍵盤事件 | 說明 |
keydown | 按下鍵盤按鍵 |
keypress | 持續按下鍵盤按鍵 |
keyup | 放開鍵盤按鍵 |
表單事件 | 說明 |
blur | 焦點離開表單元素 |
focus | 焦點進入表單元素 |
change | 元素值變更 (text, textarea) |
select | 文字被選取 (text, textarea) |
submit | 提交表單 |
focusin | 焦點進入表單元素 |
focusout | 焦點離開表單元素 |
其他事件 | 說明 |
resize | 視窗大小改變 |
scroll | 頁面或元素被捲動 |
contextmenu | 內容選單顯示之前 |
其中最常用的是按鈕的 click 事件, 例如下列按鈕 :
<button id="btn">按我</button>
呼叫 button 元素物件的 on() 方法為其綁定 click 事件 :
$("#btn").on("click", function(e){
alert("你按了按鈕!");
});
可以多個事件綁定一個事件處理函式, 各事件類型字串以空格隔開, 例如 :
$("#btn").on("click mouseover", function(e){
alert("你按了按鈕!");
});
傳入第二參數 data 可將資料以鍵值對 (物件) 傳遞給事件物件 e, 在回呼函數中可用 e.data.屬性名稱取值, 例如 :
$("#btn").on("click", {"name":"Tony"}, function(e){
alert(e.data.name + " 按了按鈕!"); //顯示 "Tony 按了按鈕"
})
對於這些事件, jQuery 物件也有捷徑方法可以直接綁定事件處理函式 (語法較簡短), 例如 :
$("#btn").click(function(e){
alert("你按了按鈕!");
})
捷徑方法也可以傳遞 data 參數 (備選第一參數) :
$("#btn").click({"name":"Tony"}, function(e){
alert(e.data.name + " 按了按鈕!"); //顯示 "Tony 按了按鈕"
})
如果要替元素綁定多個事件, 可以用鏈式呼叫 on(), 例如 :
$("#btn").on("click", function(e){
console.log("按了按鈕!");
}).on("mouseover", function(e){
console.log("滑鼠滑過按鈕!");
});
也可以用事件雜湊來一次綁定多個事件 (為了可讀性可將事件處理函式命名), 例如 :
var eh1=function(e){console.log("按了按鈕!");};
var eh2=function(e){console.log("滑過按鈕!");};
$("#btn").on({click: eh1, mouseover: eh2}); // 鍵用字串 "click": eh1 也可以
傳遞資料的範例如下 (注意, data 是放在第二參數) :
var eh1=function(e){console.log(e.data.name + "按了按鈕!");};
var eh2=function(e){console.log("滑過按鈕!");};
$("#btn").on({click: eh1, mouseover: eh2},{"name":"Tony"});
事件物件 e 常用的屬性除 data 外還有表示滑鼠位置的 pageX 與 pageY; 常用方法有停止元素預設動作 (例如表單元素 form 之提交, 超連結元素 a 的重導向, 或核取方塊狀態之變化等) 的 preventDefault() 與停止事件沿 DOM 樹向上傳遞的 stopPropagation(). 典型的範例是以超連結當按鈕使用時, 必須於事件處理函式結尾以 return false 避免除新載入頁面, 這與連續呼叫 preventDefault() 與 stopPropagation() 效果相同.
有些情況需要取消事件綁定, 這可用呼叫 off() 達成, 其 API 如下 :
obj.off(eventType [, selector] [, handler])
obj.off(eventsHash [, selector]])
例如 :
$("#btn").off("click mouseover");
9. 用 Ajax 取得遠端網頁或資料 :
Ajax 必須有後端伺服器配合才行, 在本機無法運作. jQuery 的 Ajax 函式與方法主要是由頂層函數 $.ajax(), 頂層捷徑函數 $.get(), $.post 與 $.getJSON(), 以及 jQuery 物件方法 obj.load() 構成, 其中 $.ajax() 是最底層函數, 其它函數與方法均以 $.ajax() 為基礎.
呼叫 $.ajax() 時必須傳入一個設定物件, 主要屬性與方法如下 :
$.ajax() 常用屬性 | 說明 |
url | HTTP 請求的目標網址 (字串) |
type | HTTP 請求的方式 ("GET" 或 "POST"), 預設為 "GET" |
data | 請求附帶的參數資料, 可用物件 {a:1, b: 2} 或字串例如 "a=1&b=2" |
dataType | 預期伺服器回應的資料類型字串 (text/html/xml/json/script/jsonp) |
success | 請求成功時要執行之回呼函數, function(data, textStatus) |
error | 請求失敗時要執行之回呼函數, function(XMLHttpRequest, textStatus) |
complete | 請求送出時要執行之回呼函數, function(XMLHttpRequest, textStatus) |
beforeSend | 請求送出前要執行之回呼函數, function(XMLHttpRequest) |
cache | 是否在記憶體快取此結果 (布林值), 預設為 true |
伺服端的 Ajax 回應資料會傳入 success 屬性值的回呼函數參數 data 中, 例如載入遠端伺服器上的 HTML 檔 test.htm 時, 可將回應網頁從回呼函數參數 data 中取出後用 html() 方法填入 id=result 的指定元素內容中 :
$.ajax({
type: "GET",
url: "test.htm",
dataType: "html",
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
動態網頁需要傳遞參數給伺服端的程式處理, 傳遞參數通常用 POST 方式將參數放在 HTTP 的 body 中傳送, 也可以用 GET 方式放在 HTTP 標頭中傳遞. 參數可以附在 url 屬性後面以查詢字串方式傳遞; 也可以用鍵值對方式放在 data 屬性中傳遞, 後端程式擷取 HTTP 參數的方式以 PHP 而言可用 $_GET[] 或 $_POST[] 取得, 但要視參數是放在 url 或 data 屬性而定 :
- type=GET :
不論 url 或 data 的參數一律轉成查詢字串在標頭中傳送, 後端要用 $_GET[] 擷取參數. - type=POST :
url 參數在標頭中傳送, 用 $_GET[] 擷取; data 參數在本體中傳送, 用 $_POST[] 擷取.
$.ajax({
type: "POST",
url: "test.php",
dataType: "html",
data: {user: "tony", pwd: 123},
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
回應 HTML 資料的後端 PHP 範例如下 (注意 header) :
<?php
header("Content-Type: text/html; charset: utf-8");
echo "<p>get :user=".$_GET['user'].", pwd=".$_GET['pwd']."</p>".
"<p>post : user=".$_POST['user'].", pwd=".$_POST['pwd']."</p>".
"<p>post : user=".$_REQUEST['user'].", pwd=".$_REQUEST['pwd']."</p>".
"<p style='font-weight:bold;'>Hello World!</p>".
"<p id='normal'>Hello World!</p>";
?>
實際應用上是將表單元素之輸入值提交給後端伺服器, 表單元素 form 的 jQuery 物件有一個 serialize() 方法可將表單內有 name 屬性的元件輸入值轉成查詢字串, 例如下列登入表單 :
<form id="login_form">
<label for="user">帳號 : </label>
<input type="text" id="user" name="user"><br>
<label for="pwd">密碼 : </label>
<input type="text" id="pwd" name="pwd">
<button id="login">登入</button>
</form>
可用 $("#login_form").serialize() 將表單內的輸入元件值轉成 "user=tony&pwd=12345" 的查詢字串傳遞到後端, 例如 :
$.ajax({
type: "POST",
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
},
error: function(xhr) {
alert(xhr.status);
}
});
除了 $.ajax() 外 jQuery 還提供較高階的捷徑函數, 較常用的是這三個 :
- $.get() : 以 GET 方法取得遠端伺服器檔案
- $.post() : 以 POST 方法取得遠端伺服器檔案
- $.getJSON() : 以 POST 方法取得遠端伺服器 JSON 檔案
$.get({
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
}
});
呼叫 $.post() 則以 POST 方式發出請求 :
$.post({
url: "test.php",
dataType: "html",
data: $("#login_form").serialize(),
success: function(data) {
$("#result").html(data);
}
});
若僅僅是查詢資料, 伺服端更精簡的方式是直接回應 JSON 資料再填入網頁內, 例如 :
{"user":"tony","pwd":"123"}
回應此資料之後端程式 test_json.php 如下 :
<?php
header("Content-Type: application/json");
$user=$_REQUEST["user"];
$pwd=$_REQUEST["pwd"];
$response=array(
'user' => 'tony',
'pwd' => '123'
);
echo json_encode($response);
?>
用 POST 查詢 JSON 資料 :
$.post({
url: "test_json.php",
data: $("#login_form").serialize(),
success: function(data) {
var user=data.user;
var pwd=data.pwd;
var result="帳號=" + user + " 密碼=" + pwd;
$("#result").html(result);
}
});
用捷徑函數 $.getJSON() 請求 JSON 資料 :
$.getJSON({
url: "test_json.php",
data: $("#login_form").serialize(),
success: function(data) {
var user=data.user;
var pwd=data.pwd;
var result="帳號=" + user + " 密碼=" + pwd;
$("#result").html(result);
}
});
詳細測試參考 :
# 測試 jQuery 的 Ajax 函數 $.ajax()
# jQuery 的 Ajax 捷徑函數測試
# 測試 jQuery 的 Ajax 方法 load()
三. 工具函數 (utilities) :
jQuery 的工具函數是定義在頂層命名空間的函數, 而非任何 jQuery 物件之方法, 因此可用 jQuery. 或 $. 直接呼叫, 以下是較常用的函數 :
1. 迭代 (迴圈) 函數 $.each() :
此函數可用來迭代陣列與物件, 但不能用來迭代字串中的字元 (迭代字串要用 for in 或 for of).
$.each(array/object, function(key/index, value))
第一個參數是要迭代的陣列或物件, 第二個參數是處理迭代過程的回呼函數. 回呼函數的第一參數是陣列的索引或物件的屬性 (鍵), 第二參數是元素或屬性之值. $.each() 的主要作用場域是在回呼函數而非傳回值, 其傳回值為第一參數 (即被跌代的物件或陣列).
陣列的迭代範例如下 :
var arr=["a", "b", "c"];
$.each(arr, function(idx, value){
document.write("arr[" + idx + "]=" + value + ", ");
});
結果輸出 arr[0]=a, arr[1]=b, arr[2]=c,.
物件迭代的範例如下 :
var obj={name:"tony", gender:"male", age:18};
$.each(obj, function(key, value){
document.write("obj." + key + "=" + value + ", ");
});
結果輸出 obj.name=tony, obj.gender=male, obj.age=18,.
2. 陣列過濾函數 $.grep() :
此函數用來過濾陣列中的元素, 它有 1~3 個可能參數, 傳回值為一個陣列, API 如下 :
var arr=$.grep(array, function(value [, index]) [, invert]) {})
第一個參數是要過濾的陣列, 第二參數是負責過濾的回呼函數, 其第一參數為陣列之元素值, 第二可選參數為其索引, 第三參數為布林值, 預設為 false (正向過濾).
在迭代陣列中的每一個元素時, 回呼函數必須用條件運算傳回 true 或 false, 如果傳回 true, 則此元素會被 $.grep() 傳回給接收陣列 arr; 否則不會被傳回, 此即正向過濾功能. 若回呼函數第三參數 invert 傳入 true 則剛好相反, 即只有回呼函數傳回 false 時將元素回傳給接收陣列 (反向過濾), 範例如下 :
var arr1=[34,78,99,84,56,22,100];
詳細測試請參考 :
# jQuery 的工具函數測試
四. 實用範例 :
以下摘要整理一些常用的實用範例.
1. 觸發滑鼠移動事件 (mousemove) 顯示座標 :
此例網頁中有一 p 元素用來顯示滑鼠座標位置 :
<p></p>
當滑鼠移動時, 它會觸動 window 物件的 mousemove 事件, 可以利用事件物件之 pageX 與 pageY 屬性取得滑鼠位置之 (x, y) 座標 :
$(window).mousemove(function(e){
$("p").html("X=" + e.pageX + " Y=" + e.pageY);
});
參考 :
# [Jquery] 複選的checkbox取值
# [jQuery] checkbox 及 radio 設定值
# [jQuery] select 元件的取值及給值
# [Javascript/Jquery] 移除textarea中空行、空白行
$.post({
url: "test_json.php",
data: $("#login_form").serialize(),
success: function(data) {
var user=data.user;
var pwd=data.pwd;
var result="帳號=" + user + " 密碼=" + pwd;
$("#result").html(result);
}
});
用捷徑函數 $.getJSON() 請求 JSON 資料 :
$.getJSON({
url: "test_json.php",
data: $("#login_form").serialize(),
success: function(data) {
var user=data.user;
var pwd=data.pwd;
var result="帳號=" + user + " 密碼=" + pwd;
$("#result").html(result);
}
});
詳細測試參考 :
# 測試 jQuery 的 Ajax 函數 $.ajax()
# jQuery 的 Ajax 捷徑函數測試
# 測試 jQuery 的 Ajax 方法 load()
三. 工具函數 (utilities) :
jQuery 的工具函數是定義在頂層命名空間的函數, 而非任何 jQuery 物件之方法, 因此可用 jQuery. 或 $. 直接呼叫, 以下是較常用的函數 :
1. 迭代 (迴圈) 函數 $.each() :
此函數可用來迭代陣列與物件, 但不能用來迭代字串中的字元 (迭代字串要用 for in 或 for of).
$.each(array/object, function(key/index, value))
第一個參數是要迭代的陣列或物件, 第二個參數是處理迭代過程的回呼函數. 回呼函數的第一參數是陣列的索引或物件的屬性 (鍵), 第二參數是元素或屬性之值. $.each() 的主要作用場域是在回呼函數而非傳回值, 其傳回值為第一參數 (即被跌代的物件或陣列).
陣列的迭代範例如下 :
var arr=["a", "b", "c"];
$.each(arr, function(idx, value){
document.write("arr[" + idx + "]=" + value + ", ");
});
結果輸出 arr[0]=a, arr[1]=b, arr[2]=c,.
物件迭代的範例如下 :
var obj={name:"tony", gender:"male", age:18};
$.each(obj, function(key, value){
document.write("obj." + key + "=" + value + ", ");
});
結果輸出 obj.name=tony, obj.gender=male, obj.age=18,.
2. 陣列過濾函數 $.grep() :
此函數用來過濾陣列中的元素, 它有 1~3 個可能參數, 傳回值為一個陣列, API 如下 :
var arr=$.grep(array, function(value [, index]) [, invert]) {})
第一個參數是要過濾的陣列, 第二參數是負責過濾的回呼函數, 其第一參數為陣列之元素值, 第二可選參數為其索引, 第三參數為布林值, 預設為 false (正向過濾).
在迭代陣列中的每一個元素時, 回呼函數必須用條件運算傳回 true 或 false, 如果傳回 true, 則此元素會被 $.grep() 傳回給接收陣列 arr; 否則不會被傳回, 此即正向過濾功能. 若回呼函數第三參數 invert 傳入 true 則剛好相反, 即只有回呼函數傳回 false 時將元素回傳給接收陣列 (反向過濾), 範例如下 :
var arr1=[34,78,99,84,56,22,100];
var arr2=$.grep(arr1, function(value){ //過濾元素值
return value >= 60; //傳回及格分數 arr2=[78,99,84,100]
return value >= 60; //傳回及格分數 arr2=[78,99,84,100]
});
3. 陣列或物件用 $.map() 轉換 :
此函數可在迭代陣列元素或物件屬性的過程中, 於回呼函數裏透過運算傳回新陣列元素, 傳回值為一個陣列, API 如下 :
var arr=$.map(array/object, function(value [, index/attr]){})
第一參數為待轉換陣列或物件, 第二參數為回呼函數, 回呼函數的第一參數為陣列元素或物件屬性之值, 備選之第二參數為索引或屬性 (鍵). 此函數 API 與功能與 $.grep() 很像, 都是傳回一個陣列, 差別在於 $.grep() 回呼函數利用 return true/false 來控制要不要傳回原陣列元素, 而 $.map() 回呼函數中的 return 是直接傳回新陣列元素值, 例如 :
var score=[34,78,99,84,56,22,100];
var arr=$.map(score, function(value){
return value < 60 ? value + 5 : value; //不及格分數加 5 分後傳回
});
結果傳回新陣列 arr=[39,78,99,84,61,27,100]. 如果傳回 null 則新陣列不會增加新元素, 例如 :
var score=[34,78,99,84,56,22,100];
var arr=$.map(score, function(value){
return value < 60 ? null : value; //傳回及格者分數
});
結果傳回新陣列 arr=[78,99,84,100].
4. 陣列合併函數 $.merge() :
此函數可合併兩個陣列, 其 API 如下 :
var arr=$.merge(array1, array2)
合併後的新陣列為 array1 並且被傳回, 而 array2 則不變, 例如 :
var arr1=[1,2,3];
var arr2=[4,5,6];
var arr3=$.merge(arr1, arr2);
合併後 arr1 與傳回值 arr3 結果都是 [1,2,3,4,5,6], 而 arr2 仍為 [4,5,6] 不變.
5. 用 $.inArray() 檢查陣列中是否含有特定元素 :
函數 $.inArray() 之 API 如下 :
var idx=$.inArray(value, array [, fromIndex])
第一參數為要檢查之元素, 第二參數為陣列, 可選之第三參數為開始檢查之索引 (預設 0), 如果有找到就傳回該元素之索引, 否則傳回 -1, 例如 :
var arr3=$.grep(arr1, function(value, index, true){ //過濾元素值
return value >= 60; //傳回不及格分數 arr3=[34,56,22]
return value >= 60; //傳回不及格分數 arr3=[34,56,22]
});
3. 陣列或物件用 $.map() 轉換 :
此函數可在迭代陣列元素或物件屬性的過程中, 於回呼函數裏透過運算傳回新陣列元素, 傳回值為一個陣列, API 如下 :
var arr=$.map(array/object, function(value [, index/attr]){})
第一參數為待轉換陣列或物件, 第二參數為回呼函數, 回呼函數的第一參數為陣列元素或物件屬性之值, 備選之第二參數為索引或屬性 (鍵). 此函數 API 與功能與 $.grep() 很像, 都是傳回一個陣列, 差別在於 $.grep() 回呼函數利用 return true/false 來控制要不要傳回原陣列元素, 而 $.map() 回呼函數中的 return 是直接傳回新陣列元素值, 例如 :
var score=[34,78,99,84,56,22,100];
var arr=$.map(score, function(value){
return value < 60 ? value + 5 : value; //不及格分數加 5 分後傳回
});
結果傳回新陣列 arr=[39,78,99,84,61,27,100]. 如果傳回 null 則新陣列不會增加新元素, 例如 :
var score=[34,78,99,84,56,22,100];
var arr=$.map(score, function(value){
return value < 60 ? null : value; //傳回及格者分數
});
結果傳回新陣列 arr=[78,99,84,100].
4. 陣列合併函數 $.merge() :
此函數可合併兩個陣列, 其 API 如下 :
var arr=$.merge(array1, array2)
合併後的新陣列為 array1 並且被傳回, 而 array2 則不變, 例如 :
var arr1=[1,2,3];
var arr2=[4,5,6];
var arr3=$.merge(arr1, arr2);
合併後 arr1 與傳回值 arr3 結果都是 [1,2,3,4,5,6], 而 arr2 仍為 [4,5,6] 不變.
5. 用 $.inArray() 檢查陣列中是否含有特定元素 :
函數 $.inArray() 之 API 如下 :
var idx=$.inArray(value, array [, fromIndex])
第一參數為要檢查之元素, 第二參數為陣列, 可選之第三參數為開始檢查之索引 (預設 0), 如果有找到就傳回該元素之索引, 否則傳回 -1, 例如 :
var fruits=["apple", "grape", "guava"];
var idx=$.inArray("grape", fruits); //陣列中有此元素, 傳回其索引 1
var idx=$.inArray("pineapple", fruits); //陣列中無此元素, 傳回 -1
詳細測試請參考 :
# jQuery 的工具函數測試
四. 實用範例 :
以下摘要整理一些常用的實用範例.
1. 觸發滑鼠移動事件 (mousemove) 顯示座標 :
此例網頁中有一 p 元素用來顯示滑鼠座標位置 :
<p></p>
當滑鼠移動時, 它會觸動 window 物件的 mousemove 事件, 可以利用事件物件之 pageX 與 pageY 屬性取得滑鼠位置之 (x, y) 座標 :
$(window).mousemove(function(e){
$("p").html("X=" + e.pageX + " Y=" + e.pageY);
});
參考 :
# [Jquery] 複選的checkbox取值
# [jQuery] checkbox 及 radio 設定值
# [jQuery] select 元件的取值及給值
# [Javascript/Jquery] 移除textarea中空行、空白行
標籤:
♥♥
,
網頁技術
,
Javascript
,
jQuery
,
jQuery UI
反應: |
2020年8月23日 星期日
2020 年第 34 周記事
週五水某與菁菁作自強號上台北找姊姊 (安心旅遊專案), 雖然巴威颱風來襲, 但只到花東, 還好只是帶來南部的雨水.
暑假已近尾聲, 二哥的打工生涯也即將在 8/26 結束, 下班要直接回高雄, 因為週三要赴座談會提出報告. 本來是應徵課輔, 後來被建議改為企劃, 其實就是總務啦, 包括點貨, 搬米, 裝箱, 招待, 維持學生秩序 ... 相信近兩個月下來體驗應該很多, 收穫是得到自己的第一個資產 ~~~ 電動機車. 月底菁菁開學我又要開始早起的生活了.
過去一周為了工作上的需要回頭改寫 jQuery UI 為基礎的作業自動化系統, 所以 R 語言暫停, 希望用兩周的時間把這搞定, 順便把 jQuery 的書整理完畢還圖書館, 因為母校借的書 R 語言書籍有兩本被 recall, 還有三周要還, 所以弄完 jQuery 要努力看 R 的書了.
阿蘭仍住院中, 因護理師通知我安素已快用完, 故週五去永茂買了一箱 (1050 元) 提前於晚上回鄉下順路拿去, 聽護理師說一天約 4~6 罐, 下周四若出院就還夠, 但不確定何時可出院, 故今早又去鎮上藥局買一箱 (1350 元), 下午 13:30 探病截止前送過去.
表弟安安的小孩帶回家了, 今日滿 15 天, 傳來的照片看來頭好壯壯, 據小舅說第一天兩夫妻不知如何為寶寶洗澡, 故小舅媽專程回去示範. 想到我家三隻小狐狸回家第一天開始都是我在幫她們洗澡, 覺得自己還是非常自豪.
上週在 Line TV 看完韓劇 "365:逆轉命運的一年", 劇情改編自日本推理小說, 描述警官池亨柱因為前輩朴善浩被出獄的嫌犯殺害而灰心失志, 半年後接到一位精神科醫師李信的電話邀約, 說她找到一個回到過去的方法 (但只能到一年前), 池亨柱為了回到一年前改變歷史便答應參加了. 但一起回到一年前的團員卻陸續被殺害, 誰是幕後的黑手呢? 池亨柱與也是團員的漫畫家申佳賢 (南志鉉飾) 在死亡威脅中一步步揭開內幕.
# https://www.linetv.tw/drama/11420/eps/1 (Line TV)
目前正在愛奇藝看的 "優雅的朋友們" 今天也將播出最後一集, 好期待.
暑假已近尾聲, 二哥的打工生涯也即將在 8/26 結束, 下班要直接回高雄, 因為週三要赴座談會提出報告. 本來是應徵課輔, 後來被建議改為企劃, 其實就是總務啦, 包括點貨, 搬米, 裝箱, 招待, 維持學生秩序 ... 相信近兩個月下來體驗應該很多, 收穫是得到自己的第一個資產 ~~~ 電動機車. 月底菁菁開學我又要開始早起的生活了.
過去一周為了工作上的需要回頭改寫 jQuery UI 為基礎的作業自動化系統, 所以 R 語言暫停, 希望用兩周的時間把這搞定, 順便把 jQuery 的書整理完畢還圖書館, 因為母校借的書 R 語言書籍有兩本被 recall, 還有三周要還, 所以弄完 jQuery 要努力看 R 的書了.
阿蘭仍住院中, 因護理師通知我安素已快用完, 故週五去永茂買了一箱 (1050 元) 提前於晚上回鄉下順路拿去, 聽護理師說一天約 4~6 罐, 下周四若出院就還夠, 但不確定何時可出院, 故今早又去鎮上藥局買一箱 (1350 元), 下午 13:30 探病截止前送過去.
表弟安安的小孩帶回家了, 今日滿 15 天, 傳來的照片看來頭好壯壯, 據小舅說第一天兩夫妻不知如何為寶寶洗澡, 故小舅媽專程回去示範. 想到我家三隻小狐狸回家第一天開始都是我在幫她們洗澡, 覺得自己還是非常自豪.
上週在 Line TV 看完韓劇 "365:逆轉命運的一年", 劇情改編自日本推理小說, 描述警官池亨柱因為前輩朴善浩被出獄的嫌犯殺害而灰心失志, 半年後接到一位精神科醫師李信的電話邀約, 說她找到一個回到過去的方法 (但只能到一年前), 池亨柱為了回到一年前改變歷史便答應參加了. 但一起回到一年前的團員卻陸續被殺害, 誰是幕後的黑手呢? 池亨柱與也是團員的漫畫家申佳賢 (南志鉉飾) 在死亡威脅中一步步揭開內幕.
# https://www.linetv.tw/drama/11420/eps/1 (Line TV)
目前正在愛奇藝看的 "優雅的朋友們" 今天也將播出最後一集, 好期待.
標籤:
生活
反應: |
2020年8月22日 星期六
jQuery UI SPA 應用程式 (五) : 字串處理函式庫
今天進入 jQuery UI 應用程式重頭戲 : 字串處理函式庫, 因為從遠端機台擷取到的純文字資料有其特定格式, 必須利用文字處理函數進行清洗, 再餵給 DataTables 表格呈現與篩選, 或者用來產生要下給遠端機台的指令, 所以字串處理可說是整個自動化專案中的關鍵工具.
這個函式庫的來源有兩個, 一是以前用 PHP 寫爬蟲程式時找到的一本好書 :
# 網路機器人, 網路蜘蛛與網路爬蟲-PHP/CURL 程式設計指南 (第二版, 碁峰出版)
其範例程式下載網址如下 :
# http://webbotsspidersscreenscrapers.com/
# http://webbotsspidersscreenscrapers.com/DSP_download.php
我參考了其中的字串剖析函式庫 LIB_parse.php 進行改寫, 裡面的兩個函數 return_between() 與 parse_array() 是此函式庫的主角, 也是進行文本剖析的利器. 另外一個參考來源是網路上的 Python 字串處理函式庫:
# http://docs.python.org/release/2.5.2/lib/string-methods.html
我將這些 PHP 與 Python 字串處理函式改寫為如下之 Javascript 版, 每一個函數都指派為 String 物件的 prototype 屬性以擴充 String 物件的功能, 這樣用法就與 Javascript 字串物件的函數完全一樣了 :
//parse.js
String.prototype.split_string=split_string;
String.prototype.return_between=return_between;
String.prototype.parse_array=parse_array;
String.prototype.remove=remove;
String.prototype.get_attribute=get_attribute;
String.prototype.trim=trim;
String.prototype.ltrim=ltrim;
String.prototype.rtrim=rtrim;
String.prototype.isdigit=isdigit;
String.prototype.startswith=startswith;
String.prototype.endswith=endswith;
String.prototype.title=title;
String.prototype.swapcase=swapcase;
String.prototype.zfill=zfill;
String.prototype.ljust=ljust;
String.prototype.rjust=rjust;
String.prototype.encode=encode;
String.prototype.decode=decode;
/*-----------------------------------------------------------------------------
split_string(delineator, desired, type)
功能 :
此函數會在一個待剖析字串中搜尋指定之界定字串 delineator, 依據所需要的位置
desired, 傳回在該界定字串之前或之後的子字串, 型態 type 用來設定傳回值中是否
要包含界定字串. 此函數所處理之字串與大小寫無關 (包括參數).
參數 :
delineator : 界定字串
desired : "before" : 傳回界定字串前之子字串
"after" : 傳回界定字串後之子字串
type : "incl" : 包含界定字串
"excl" : 不包含界定字串
-----------------------------------------------------------------------------*/
function split_string(delineator, desired, type) {
//處理預設值
var desired = String(desired).toLowerCase() || "before";
var type = String(type).toLowerCase() || "excl";
//為與大小寫無關, 全部轉為小寫處理
var lc_str = String(this).toLowerCase();
var marker = delineator.toLowerCase();
if (lc_str.indexOf(marker, 0) == -1) { //沒找到分割字串:傳回 ""
return "";
}
else { //有找到分割字串
if (desired == "before") { //傳回分割字串前的部分
if (type == "excl") { //不包含分割字串:不必加分割字串本身
var split_here = lc_str.indexOf(marker, 0);
}
else { //包含分割字串:要加計分割字串本身
var split_here = lc_str.indexOf(marker, 0) + marker.length;
}
var parsed_string = this.substring(0, split_here);
}
else { //傳回界定字串後的部分 "after"
if (type == "excl") { //不包含分割字串:要扣除分割字串本身
var split_here = lc_str.indexOf(marker, 0) + marker.length;
}
else { //包含分割字串:要加計分割字串本身
var split_here = lc_str.indexOf(marker, 0);
}
var parsed_string = this.substring(split_here, lc_str.length + 1);
}
}
return parsed_string;
}
/*-----------------------------------------------------------------------------
return_between(start, stop, type)
功能 :
此函數會在待剖析字串字串中搜尋指定之起始字串 start 與結束字串 stop, 傳回在該組
界定字串之間的子字串, 型態 type 用來設定傳回值中是否要包含組界定字串.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
type : "incl" : 包含界定字串
"excl" : 不包含界定字串
-----------------------------------------------------------------------------*/
function return_between(start, stop, type) {
//傳回起始字串後面的部分
var temp = this.split_string(start, "AFTER", type);
//傳回結束字串前面的部分
return temp.split_string(stop, "BEFORE", type);
}
/*-----------------------------------------------------------------------------
parse_array(start, stop)
功能 :
此函數會在待剖析字串字串中重複搜尋指定之起始字串 start 與結束字串 stop 間的
子字串, 並把每次符合的子字串放入陣列中傳回. 傳回值為陣列, 元素中包含界定字串.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
-----------------------------------------------------------------------------*/
function parse_array(start, stop) {
var reg=new RegExp("(" + start + "([\\s\\S]*?)" + stop + ")","ig");
return this.match(reg); //傳回符合之陣列
}
/*-----------------------------------------------------------------------------
remove(start, stop)
功能 :
此函數會在待剖析字串中重複搜尋指定之起始字串 start 與結束字串 stop 間的
子字串, 並把每次符合的子字串從待剖析字串中刪除. 傳回值為刪除後之字串.
注意, 刪除子字串時會連同界定字串一起刪除.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
-----------------------------------------------------------------------------*/
function remove(start, stop) {
var remove_array = this.parse_array(start, stop); //傳回要移除的子字串陣列
var string = this;
if (remove_array != null) { //有找到子字串:執行刪除
for (var i = 0; i < remove_array.length; i++) { //依序移除
var reg = new RegExp(remove_array[i],"ig"); //要刪除之子字串 reg 物件
var string = string.replace(reg, "");
}
return string;
}
else {return this;} //沒有找到子字串:傳回待剖析字串本身
}
/*-----------------------------------------------------------------------------
get_attribute(attribute)
功能 :
此函數會在待剖析 HTML 字串中搜尋指定之屬性值.
參數 :
attribute : HTML 元素之屬性, 例如 style, class 等
-----------------------------------------------------------------------------*/
function get_attribute(attribute) {
var cleaned_html = this.tidy_html(); //整理 tag 元素
cleaned_html = cleaned_html.replace("\r", ""); //去除 CR
cleaned_html = cleaned_html.replace("\n", ""); //去除 LF
var start=attribute.toLowerCase() + "=\""; //屬性開頭 (全小寫)
return cleaned_html.return_between(start, "\"", "EXCL"); //回傳屬性值
}
//=====以下函數來自 VBscript=====//
/*-----------------------------------------------------------------------------
trim()
此函數會刪除字串開頭與結尾處之空白字元後傳回 (與 VBscript 之 Trim 同).
空白字元, 包括空格(space),水平定位(tab),跳頁(form-feed)與換列(linefeed),
相當於 [ \f\n\r\t\v\u00A0\u2028\u2029]
參數 :
無
-----------------------------------------------------------------------------*/
function trim() {
return this.replace(/(^\s*)|(\s*$)/g,"");
}
/*-----------------------------------------------------------------------------
ltrim()
此函數會刪除字串開頭處之空白字元後傳回 (與 VBscript 之 Ltrim 同).
參數 :
無
-----------------------------------------------------------------------------*/
function ltrim() {
return this.replace(/(^\s*)/g, "");
}
/*-----------------------------------------------------------------------------
rtrim()
此函數會刪除字串結尾處之空白字元後傳回 (與 VBscript 之 Rtrim 同).
參數 :
無
-----------------------------------------------------------------------------*/
function rtrim() {
return this.replace(/(\s*$)/g, "");
}
//======以下函數改寫自 Python=====//
//參考 : http://docs.python.org/release/2.5.2/lib/string-methods.html
/*-----------------------------------------------------------------------------
isdigit()
此函數會判斷字串內容是否全為數字 (與 Python 之 isdigit 同).
參數 :
無
-----------------------------------------------------------------------------*/
function isdigit() {
return str.match(/D/)==null;
}
/*-----------------------------------------------------------------------------
startswith(prefix[,start[, end]])
此函數會判斷字串內容是否以 prefix 開頭 (與 Python 之 startwith 同).
備選參數 start 與 end 可指定比對之起訖位置, 預設為從頭 (0) 比到尾 (length-1).
參數 :
無
-----------------------------------------------------------------------------*/
function startswith(prefix, start, end) {
var start=start || 0; //預設值
var end=end || this.length-1; //預設值
var haystack=this.substring(start,end+1);
var needle=new RegExp("^" + prefix,"ig"); //是否以 prefix 結尾 (不分大小寫)
WScript.Echo(haystack);
return needle.test(haystack);
}
/*-----------------------------------------------------------------------------
endswith(prefix[,start[, end]])
此函數會判斷字串內容是否以 prefix 開頭 (與 Python 之 startwith 同).
備選參數 start 與 end 可指定比對之起訖位置, 預設為從頭 (0) 比到尾 (length-1).
參數 :
無
-----------------------------------------------------------------------------*/
function endswith(prefix, start, end) {
var start=start || 0; //預設值
var end=end || this.length-1; //預設值
var haystack=this.substring(start,end+1);
var needle=new RegExp(prefix + "$","ig"); //是否以 prefix 結尾 (不分大小寫)
WScript.Echo(haystack);
return needle.test(haystack);
}
/*-----------------------------------------------------------------------------
title()
此函數會將字串 (英文) 中每一個字的第一個字元改成大寫, 其餘字元改為小寫後傳回
(與 Python 之 title 同).
參數 :
無
-----------------------------------------------------------------------------*/
function title() {
var words=this.replace(/[ ]{2,}/g," ").split(" "); //兩個以上連續空格改為1個
for (var i=0; i<words.length; i++) {
var first=words[i].charAt(0).toUpperCase(); //每字首字元大寫
var others=words[i].substr(1).toLowerCase(); //第2字元至最後小寫
words[i]=first + others; //重組回字
}
return words.join(" "); //重組回字串傳回
};
/*-----------------------------------------------------------------------------
swapcase(prefix[,start[, end]])
此函數會將字串 (英文) 中每一個小寫字元改成大寫, 大寫字元改成小寫後傳回
(與 Python 之 swapcase 同).
參數 :
無
-----------------------------------------------------------------------------*/
function swapcase() {
var arr=[]; //暫存字元用
var lower=/[a-z]/; //小寫字元
var upper=/[A-Z]/; //大寫字元
for (var i=0; i<this.length; i++) { //走訪每一個字元
if (lower.test(this.charAt(i))) { //小寫字母->改成大寫
arr.push(this.charAt(i).toUpperCase());
}
else if (upper.test(this.charAt(i))) { //大寫字母->改成小寫
arr.push(this.charAt(i).toLowerCase());
}
else {arr.push(this.charAt(i));}
}
return arr.join(""); //串接全部字元
};
/*-----------------------------------------------------------------------------
zfill(width)
此函數會將數字字串前面填滿 0 使得總長為 width 字元 (與 Python 之 isalnum 同).
若字串長度小於 width, 則無法填 0 而傳回字串本身.
參數 :
width : 填補之後字串總長度
傳回值 :
字串
-----------------------------------------------------------------------------*/
function zfill(width) {
var zeros=""; //補0字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿 0
for (var i=0; i<width-this.length; i++) {zeros += "0";} //製作補0字串
return zeros + this; //前面冠上補0字串
}
}
/*-----------------------------------------------------------------------------
ljust(width[, fillchar])
此函數會在字串前面以 fillchar 字元填滿使得總長為 width 字元 (與 Python 之
ljust 同). 若字串長度小於 width, 則無法填滿而傳回字串本身. fillchar 預設為
空格 space=" ".
參數 :
width : 填補之後字串總長度
fillchar : 填補字元
傳回值 :
字串
-----------------------------------------------------------------------------*/
function ljust(width, fillchar) {
var fillchar=fillchar || " "; //填補字元預設值為 " "
var filler=""; //填補字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿
for (var i=0; i<width-this.length; i++) {filler += fillchar;} //填補字串
return filler + this; //前面冠上填補字串
}
}
/*-----------------------------------------------------------------------------
rjust(width[, fillchar])
此函數會在字串後面以 fillchar 字元填滿使得總長為 width 字元 (與 Python 之
ljust 同). 若字串長度小於 width, 則無法填滿而傳回字串本身. fillchar 預設為
空格 space=" ".
參數 :
width : 填補之後字串總長度
fillchar : 填補字元
傳回值 :
字串
-----------------------------------------------------------------------------*/
function rjust(width, fillchar) {
var fillchar=fillchar || " "; //填補字元預設值為 " "
var filler=""; //填補字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿
for (var i=0; i<width-this.length; i++) {filler += fillchar;} //填補字串
return this + filler; //後面冠上填補字串
}
}
/*-----------------------------------------------------------------------------
encode(key)
此函數會依據傳入之 key 對字串進行特定編碼. 其相對之解碼函式為 decode(), 必須
傳入相同 key 才會解出原始字串.
參數 :
key : 編碼所用之鍵字串.
傳回值 :
由 key 字串中之字元編碼所組成之加密字串
源碼 : http://www.360doc.com/content/13/0806/13/1073512_305112816.shtml
-----------------------------------------------------------------------------*/
function encode(key) {
if (!key) {
var key="8ABC7DLO5MN6Z9EFGdeJfghijkHIVrstuvwWSTUXYabclmnopqKPQRxyz01234";
}
var nl=this.length;
var t=[];
var a,b,c,x,m=function(y){t[t.length]=key.charAt(y)};
var N=key.length;
var N2=N*N,N5=N*5;
for (x=0;x<nl;x++) {
a=this.charCodeAt(x);
if (a<N5) m(Math.floor(a/N)),m(a%N);
else m(Math.floor(a/N2)+5),m(Math.floor(a/N)%N),m(a%N);
}
var s=t.join("");
return String(s.length).length+String(s.length)+s;
};
/*-----------------------------------------------------------------------------
decode(key)
此函數會依據傳入之 key 對字串進行特定解碼. 其相對之編碼函式為 encode(), 必須
傳入編碼所用之相同 key 才會解出原始字串.
參數 :
key : 解碼所用之鍵字串.
傳回值 :
由 key 字串中之字元解碼所組成之還原字串
源碼 : http://www.360doc.com/content/13/0806/13/1073512_305112816.shtml
-----------------------------------------------------------------------------*/
function decode(key) {
if (!key) {
var key="8ABC7DLO5MN6Z9EFGdeJfghijkHIVrstuvwWSTUXYabclmnopqKPQRxyz01234";
}
var c=this.charAt(0)*1;
if (isNaN(c)) return "";
c=this.substr(1,c)*1;
if (isNaN(c)) return "";
var nl=this.length;
var t=[];
var a,f,b,x=String(c).length+1;
var enc=this;
var m=function(y){return key.indexOf(enc.charAt(y))};
var N=key.length;
if (nl!=x+c) return "";
while (x<nl) {
a=m(x++)
if (a<5)f=a*N+m(x);
else f=(a-5)*N*N+m(x)*N+m(x+=1);
t[t.length]=String.fromCharCode(f);
x++;
}
return t.join("");
};
其中最重要的函數是 return_between(start, end, type), 它使用正規表達式來取得目標字串, 第一個參數 start 是要擷取之資料前面之起始標記; 第二個參數 end 為結束標記, type 用來指定傳回結果是否要包含起始與結束標記, "incl" 為包含, "excl" 為不包含.
將此函式庫放在專案的 /lib 資料夾下 :
下面是這些函數的測試範例 :
範例 10 : 用 return_between() 擷取子字串
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<script src="lib/parse.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<div id="data" class="ui-state-highlight ui-corner-all" style="margin-top: 10px; margin-bottom: 10px;padding: 5px;">align="center" height="25"</div>
<button id="get_align" class="ui-button ui-widget ui-corner-all">擷取 align</button>
<button id="get_height" class="ui-button ui-widget ui-corner-all">擷取 height</button>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#get_align").click(function(e) {
e.preventDefault();
var data=$("#data").html();
var str=data.return_between('align="', '"', 'excl');
$("#msgbox").html(str);
$("#msgbox").dialog("open");
});
//監聽按鈕之 click 事件
$("#get_height").click(function(e) {
e.preventDefault();
var data=$("#data").html();
var str=data.return_between('height="', '"', 'excl');
$("#msgbox").html(str);
$("#msgbox").dialog("open");
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
});
</script>
<!-- 訊息盒 -->
<div id="msgbox" title="訊息"></div>
<script>
$(function(){
//建立訊息盒
$("#msgbox").dialog({
title: "訊息",
autoOpen: false,
buttons: {
"確定": function() {$(this).dialog("close");}
}
});
});
</script>
</body>
</html>
此網頁在 id=data 的 div 元素中放置字串內容 align="center" height="25", 按下按鈕後會呼叫 return_between() 分別擷取 align 與 height 之屬性值, 結果如下 :
可見 return_between() 可以擷取起始與結束標記之間的子字串.
下面的範例則是測試 parse_array() 函數, 此函數會將字串中多組由起始與結束標記包起來子字串都擷取出來, 放在陣列中傳回 :
範例 11 : 用 parse_array() 擷取子字串陣列
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<script src="lib/parse.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<input id="data" style="width: 100%; margin-top: 10px; margin-bottom: 10px" value="<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>"><br>
<input id="out" style="width: 100%; margin-top: 10px; margin-bottom: 10px"<br>
<button id="get_cell_content" class="ui-button ui-widget ui-corner-all">擷取儲存格中的內容</button>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#get_cell_content").click(function(e) {
var data=$("#data").val();
var arr=data.parse_array('<td>', '</td>');
$("#out").val(arr.join());
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
});
</script>
</body>
</html>
此例中有兩個 input 文字欄位, id=data 的欄位存放待剖析之字串; 而 id=out 的欄位則用來顯示 parse_array() 傳回來的陣列 (用 join 方法轉成字串), 結果如下 :
可見 parse_array() 在擷取子字串時不會刪除起始與結束標記, 這可以呼叫 replace() 方法處理.
這個函式庫的來源有兩個, 一是以前用 PHP 寫爬蟲程式時找到的一本好書 :
# 網路機器人, 網路蜘蛛與網路爬蟲-PHP/CURL 程式設計指南 (第二版, 碁峰出版)
Source : 金石堂
其範例程式下載網址如下 :
# http://webbotsspidersscreenscrapers.com/
# http://webbotsspidersscreenscrapers.com/DSP_download.php
我參考了其中的字串剖析函式庫 LIB_parse.php 進行改寫, 裡面的兩個函數 return_between() 與 parse_array() 是此函式庫的主角, 也是進行文本剖析的利器. 另外一個參考來源是網路上的 Python 字串處理函式庫:
# http://docs.python.org/release/2.5.2/lib/string-methods.html
我將這些 PHP 與 Python 字串處理函式改寫為如下之 Javascript 版, 每一個函數都指派為 String 物件的 prototype 屬性以擴充 String 物件的功能, 這樣用法就與 Javascript 字串物件的函數完全一樣了 :
//parse.js
String.prototype.split_string=split_string;
String.prototype.return_between=return_between;
String.prototype.parse_array=parse_array;
String.prototype.remove=remove;
String.prototype.get_attribute=get_attribute;
String.prototype.trim=trim;
String.prototype.ltrim=ltrim;
String.prototype.rtrim=rtrim;
String.prototype.isdigit=isdigit;
String.prototype.startswith=startswith;
String.prototype.endswith=endswith;
String.prototype.title=title;
String.prototype.swapcase=swapcase;
String.prototype.zfill=zfill;
String.prototype.ljust=ljust;
String.prototype.rjust=rjust;
String.prototype.encode=encode;
String.prototype.decode=decode;
/*-----------------------------------------------------------------------------
split_string(delineator, desired, type)
功能 :
此函數會在一個待剖析字串中搜尋指定之界定字串 delineator, 依據所需要的位置
desired, 傳回在該界定字串之前或之後的子字串, 型態 type 用來設定傳回值中是否
要包含界定字串. 此函數所處理之字串與大小寫無關 (包括參數).
參數 :
delineator : 界定字串
desired : "before" : 傳回界定字串前之子字串
"after" : 傳回界定字串後之子字串
type : "incl" : 包含界定字串
"excl" : 不包含界定字串
-----------------------------------------------------------------------------*/
function split_string(delineator, desired, type) {
//處理預設值
var desired = String(desired).toLowerCase() || "before";
var type = String(type).toLowerCase() || "excl";
//為與大小寫無關, 全部轉為小寫處理
var lc_str = String(this).toLowerCase();
var marker = delineator.toLowerCase();
if (lc_str.indexOf(marker, 0) == -1) { //沒找到分割字串:傳回 ""
return "";
}
else { //有找到分割字串
if (desired == "before") { //傳回分割字串前的部分
if (type == "excl") { //不包含分割字串:不必加分割字串本身
var split_here = lc_str.indexOf(marker, 0);
}
else { //包含分割字串:要加計分割字串本身
var split_here = lc_str.indexOf(marker, 0) + marker.length;
}
var parsed_string = this.substring(0, split_here);
}
else { //傳回界定字串後的部分 "after"
if (type == "excl") { //不包含分割字串:要扣除分割字串本身
var split_here = lc_str.indexOf(marker, 0) + marker.length;
}
else { //包含分割字串:要加計分割字串本身
var split_here = lc_str.indexOf(marker, 0);
}
var parsed_string = this.substring(split_here, lc_str.length + 1);
}
}
return parsed_string;
}
/*-----------------------------------------------------------------------------
return_between(start, stop, type)
功能 :
此函數會在待剖析字串字串中搜尋指定之起始字串 start 與結束字串 stop, 傳回在該組
界定字串之間的子字串, 型態 type 用來設定傳回值中是否要包含組界定字串.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
type : "incl" : 包含界定字串
"excl" : 不包含界定字串
-----------------------------------------------------------------------------*/
function return_between(start, stop, type) {
//傳回起始字串後面的部分
var temp = this.split_string(start, "AFTER", type);
//傳回結束字串前面的部分
return temp.split_string(stop, "BEFORE", type);
}
/*-----------------------------------------------------------------------------
parse_array(start, stop)
功能 :
此函數會在待剖析字串字串中重複搜尋指定之起始字串 start 與結束字串 stop 間的
子字串, 並把每次符合的子字串放入陣列中傳回. 傳回值為陣列, 元素中包含界定字串.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
-----------------------------------------------------------------------------*/
function parse_array(start, stop) {
var reg=new RegExp("(" + start + "([\\s\\S]*?)" + stop + ")","ig");
return this.match(reg); //傳回符合之陣列
}
/*-----------------------------------------------------------------------------
remove(start, stop)
功能 :
此函數會在待剖析字串中重複搜尋指定之起始字串 start 與結束字串 stop 間的
子字串, 並把每次符合的子字串從待剖析字串中刪除. 傳回值為刪除後之字串.
注意, 刪除子字串時會連同界定字串一起刪除.
此函數所處理之字串與大小寫無關 (包括參數).
參數 :
start : 起始字串
stop : 結束字串
-----------------------------------------------------------------------------*/
function remove(start, stop) {
var remove_array = this.parse_array(start, stop); //傳回要移除的子字串陣列
var string = this;
if (remove_array != null) { //有找到子字串:執行刪除
for (var i = 0; i < remove_array.length; i++) { //依序移除
var reg = new RegExp(remove_array[i],"ig"); //要刪除之子字串 reg 物件
var string = string.replace(reg, "");
}
return string;
}
else {return this;} //沒有找到子字串:傳回待剖析字串本身
}
/*-----------------------------------------------------------------------------
get_attribute(attribute)
功能 :
此函數會在待剖析 HTML 字串中搜尋指定之屬性值.
參數 :
attribute : HTML 元素之屬性, 例如 style, class 等
-----------------------------------------------------------------------------*/
function get_attribute(attribute) {
var cleaned_html = this.tidy_html(); //整理 tag 元素
cleaned_html = cleaned_html.replace("\r", ""); //去除 CR
cleaned_html = cleaned_html.replace("\n", ""); //去除 LF
var start=attribute.toLowerCase() + "=\""; //屬性開頭 (全小寫)
return cleaned_html.return_between(start, "\"", "EXCL"); //回傳屬性值
}
//=====以下函數來自 VBscript=====//
/*-----------------------------------------------------------------------------
trim()
此函數會刪除字串開頭與結尾處之空白字元後傳回 (與 VBscript 之 Trim 同).
空白字元, 包括空格(space),水平定位(tab),跳頁(form-feed)與換列(linefeed),
相當於 [ \f\n\r\t\v\u00A0\u2028\u2029]
參數 :
無
-----------------------------------------------------------------------------*/
function trim() {
return this.replace(/(^\s*)|(\s*$)/g,"");
}
/*-----------------------------------------------------------------------------
ltrim()
此函數會刪除字串開頭處之空白字元後傳回 (與 VBscript 之 Ltrim 同).
參數 :
無
-----------------------------------------------------------------------------*/
function ltrim() {
return this.replace(/(^\s*)/g, "");
}
/*-----------------------------------------------------------------------------
rtrim()
此函數會刪除字串結尾處之空白字元後傳回 (與 VBscript 之 Rtrim 同).
參數 :
無
-----------------------------------------------------------------------------*/
function rtrim() {
return this.replace(/(\s*$)/g, "");
}
//======以下函數改寫自 Python=====//
//參考 : http://docs.python.org/release/2.5.2/lib/string-methods.html
/*-----------------------------------------------------------------------------
isdigit()
此函數會判斷字串內容是否全為數字 (與 Python 之 isdigit 同).
參數 :
無
-----------------------------------------------------------------------------*/
function isdigit() {
return str.match(/D/)==null;
}
/*-----------------------------------------------------------------------------
startswith(prefix[,start[, end]])
此函數會判斷字串內容是否以 prefix 開頭 (與 Python 之 startwith 同).
備選參數 start 與 end 可指定比對之起訖位置, 預設為從頭 (0) 比到尾 (length-1).
參數 :
無
-----------------------------------------------------------------------------*/
function startswith(prefix, start, end) {
var start=start || 0; //預設值
var end=end || this.length-1; //預設值
var haystack=this.substring(start,end+1);
var needle=new RegExp("^" + prefix,"ig"); //是否以 prefix 結尾 (不分大小寫)
WScript.Echo(haystack);
return needle.test(haystack);
}
/*-----------------------------------------------------------------------------
endswith(prefix[,start[, end]])
此函數會判斷字串內容是否以 prefix 開頭 (與 Python 之 startwith 同).
備選參數 start 與 end 可指定比對之起訖位置, 預設為從頭 (0) 比到尾 (length-1).
參數 :
無
-----------------------------------------------------------------------------*/
function endswith(prefix, start, end) {
var start=start || 0; //預設值
var end=end || this.length-1; //預設值
var haystack=this.substring(start,end+1);
var needle=new RegExp(prefix + "$","ig"); //是否以 prefix 結尾 (不分大小寫)
WScript.Echo(haystack);
return needle.test(haystack);
}
/*-----------------------------------------------------------------------------
title()
此函數會將字串 (英文) 中每一個字的第一個字元改成大寫, 其餘字元改為小寫後傳回
(與 Python 之 title 同).
參數 :
無
-----------------------------------------------------------------------------*/
function title() {
var words=this.replace(/[ ]{2,}/g," ").split(" "); //兩個以上連續空格改為1個
for (var i=0; i<words.length; i++) {
var first=words[i].charAt(0).toUpperCase(); //每字首字元大寫
var others=words[i].substr(1).toLowerCase(); //第2字元至最後小寫
words[i]=first + others; //重組回字
}
return words.join(" "); //重組回字串傳回
};
/*-----------------------------------------------------------------------------
swapcase(prefix[,start[, end]])
此函數會將字串 (英文) 中每一個小寫字元改成大寫, 大寫字元改成小寫後傳回
(與 Python 之 swapcase 同).
參數 :
無
-----------------------------------------------------------------------------*/
function swapcase() {
var arr=[]; //暫存字元用
var lower=/[a-z]/; //小寫字元
var upper=/[A-Z]/; //大寫字元
for (var i=0; i<this.length; i++) { //走訪每一個字元
if (lower.test(this.charAt(i))) { //小寫字母->改成大寫
arr.push(this.charAt(i).toUpperCase());
}
else if (upper.test(this.charAt(i))) { //大寫字母->改成小寫
arr.push(this.charAt(i).toLowerCase());
}
else {arr.push(this.charAt(i));}
}
return arr.join(""); //串接全部字元
};
/*-----------------------------------------------------------------------------
zfill(width)
此函數會將數字字串前面填滿 0 使得總長為 width 字元 (與 Python 之 isalnum 同).
若字串長度小於 width, 則無法填 0 而傳回字串本身.
參數 :
width : 填補之後字串總長度
傳回值 :
字串
-----------------------------------------------------------------------------*/
function zfill(width) {
var zeros=""; //補0字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿 0
for (var i=0; i<width-this.length; i++) {zeros += "0";} //製作補0字串
return zeros + this; //前面冠上補0字串
}
}
/*-----------------------------------------------------------------------------
ljust(width[, fillchar])
此函數會在字串前面以 fillchar 字元填滿使得總長為 width 字元 (與 Python 之
ljust 同). 若字串長度小於 width, 則無法填滿而傳回字串本身. fillchar 預設為
空格 space=" ".
參數 :
width : 填補之後字串總長度
fillchar : 填補字元
傳回值 :
字串
-----------------------------------------------------------------------------*/
function ljust(width, fillchar) {
var fillchar=fillchar || " "; //填補字元預設值為 " "
var filler=""; //填補字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿
for (var i=0; i<width-this.length; i++) {filler += fillchar;} //填補字串
return filler + this; //前面冠上填補字串
}
}
/*-----------------------------------------------------------------------------
rjust(width[, fillchar])
此函數會在字串後面以 fillchar 字元填滿使得總長為 width 字元 (與 Python 之
ljust 同). 若字串長度小於 width, 則無法填滿而傳回字串本身. fillchar 預設為
空格 space=" ".
參數 :
width : 填補之後字串總長度
fillchar : 填補字元
傳回值 :
字串
-----------------------------------------------------------------------------*/
function rjust(width, fillchar) {
var fillchar=fillchar || " "; //填補字元預設值為 " "
var filler=""; //填補字串初始值
if (width < this.length) {return this;} //width小於字串長度:不用補,傳回本身
else { //需要補滿
for (var i=0; i<width-this.length; i++) {filler += fillchar;} //填補字串
return this + filler; //後面冠上填補字串
}
}
/*-----------------------------------------------------------------------------
encode(key)
此函數會依據傳入之 key 對字串進行特定編碼. 其相對之解碼函式為 decode(), 必須
傳入相同 key 才會解出原始字串.
參數 :
key : 編碼所用之鍵字串.
傳回值 :
由 key 字串中之字元編碼所組成之加密字串
源碼 : http://www.360doc.com/content/13/0806/13/1073512_305112816.shtml
-----------------------------------------------------------------------------*/
function encode(key) {
if (!key) {
var key="8ABC7DLO5MN6Z9EFGdeJfghijkHIVrstuvwWSTUXYabclmnopqKPQRxyz01234";
}
var nl=this.length;
var t=[];
var a,b,c,x,m=function(y){t[t.length]=key.charAt(y)};
var N=key.length;
var N2=N*N,N5=N*5;
for (x=0;x<nl;x++) {
a=this.charCodeAt(x);
if (a<N5) m(Math.floor(a/N)),m(a%N);
else m(Math.floor(a/N2)+5),m(Math.floor(a/N)%N),m(a%N);
}
var s=t.join("");
return String(s.length).length+String(s.length)+s;
};
/*-----------------------------------------------------------------------------
decode(key)
此函數會依據傳入之 key 對字串進行特定解碼. 其相對之編碼函式為 encode(), 必須
傳入編碼所用之相同 key 才會解出原始字串.
參數 :
key : 解碼所用之鍵字串.
傳回值 :
由 key 字串中之字元解碼所組成之還原字串
源碼 : http://www.360doc.com/content/13/0806/13/1073512_305112816.shtml
-----------------------------------------------------------------------------*/
function decode(key) {
if (!key) {
var key="8ABC7DLO5MN6Z9EFGdeJfghijkHIVrstuvwWSTUXYabclmnopqKPQRxyz01234";
}
var c=this.charAt(0)*1;
if (isNaN(c)) return "";
c=this.substr(1,c)*1;
if (isNaN(c)) return "";
var nl=this.length;
var t=[];
var a,f,b,x=String(c).length+1;
var enc=this;
var m=function(y){return key.indexOf(enc.charAt(y))};
var N=key.length;
if (nl!=x+c) return "";
while (x<nl) {
a=m(x++)
if (a<5)f=a*N+m(x);
else f=(a-5)*N*N+m(x)*N+m(x+=1);
t[t.length]=String.fromCharCode(f);
x++;
}
return t.join("");
};
其中最重要的函數是 return_between(start, end, type), 它使用正規表達式來取得目標字串, 第一個參數 start 是要擷取之資料前面之起始標記; 第二個參數 end 為結束標記, type 用來指定傳回結果是否要包含起始與結束標記, "incl" 為包含, "excl" 為不包含.
將此函式庫放在專案的 /lib 資料夾下 :
下面是這些函數的測試範例 :
範例 10 : 用 return_between() 擷取子字串
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<script src="lib/parse.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<div id="data" class="ui-state-highlight ui-corner-all" style="margin-top: 10px; margin-bottom: 10px;padding: 5px;">align="center" height="25"</div>
<button id="get_align" class="ui-button ui-widget ui-corner-all">擷取 align</button>
<button id="get_height" class="ui-button ui-widget ui-corner-all">擷取 height</button>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#get_align").click(function(e) {
e.preventDefault();
var data=$("#data").html();
var str=data.return_between('align="', '"', 'excl');
$("#msgbox").html(str);
$("#msgbox").dialog("open");
});
//監聽按鈕之 click 事件
$("#get_height").click(function(e) {
e.preventDefault();
var data=$("#data").html();
var str=data.return_between('height="', '"', 'excl');
$("#msgbox").html(str);
$("#msgbox").dialog("open");
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
});
</script>
<!-- 訊息盒 -->
<div id="msgbox" title="訊息"></div>
<script>
$(function(){
//建立訊息盒
$("#msgbox").dialog({
title: "訊息",
autoOpen: false,
buttons: {
"確定": function() {$(this).dialog("close");}
}
});
});
</script>
</body>
</html>
此網頁在 id=data 的 div 元素中放置字串內容 align="center" height="25", 按下按鈕後會呼叫 return_between() 分別擷取 align 與 height 之屬性值, 結果如下 :
可見 return_between() 可以擷取起始與結束標記之間的子字串.
下面的範例則是測試 parse_array() 函數, 此函數會將字串中多組由起始與結束標記包起來子字串都擷取出來, 放在陣列中傳回 :
範例 11 : 用 parse_array() 擷取子字串陣列
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<script src="lib/parse.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<input id="data" style="width: 100%; margin-top: 10px; margin-bottom: 10px" value="<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td>"><br>
<input id="out" style="width: 100%; margin-top: 10px; margin-bottom: 10px"<br>
<button id="get_cell_content" class="ui-button ui-widget ui-corner-all">擷取儲存格中的內容</button>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#get_cell_content").click(function(e) {
var data=$("#data").val();
var arr=data.parse_array('<td>', '</td>');
$("#out").val(arr.join());
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
});
</script>
</body>
</html>
此例中有兩個 input 文字欄位, id=data 的欄位存放待剖析之字串; 而 id=out 的欄位則用來顯示 parse_array() 傳回來的陣列 (用 join 方法轉成字串), 結果如下 :
可見 parse_array() 在擷取子字串時不會刪除起始與結束標記, 這可以呼叫 replace() 方法處理.
反應: |
Win10 的全形半形切換 (Shift + Space)
今天又遇到一個長久以來使用 Win10 常遇到的問題, 就是在飛快打字時突然變成全形模式, 輸入的英文字變成粗體且間隔變大的字, 不知道是錯按了甚麼鍵造成, 只好在輸入英文時點右下角語言按鈕, 將中文改為英文, 切來切去很不方便. 今天又遇到了, 就上網查了一下, 原來是誤按了 Shift + Space 所致, 只要再按一次就會切換回半形了, 參考 :
# Win10教學︰win10切換全形半形教學
# Win10教學︰win10切換全形半形教學
標籤:
電腦
反應: |
2020年8月21日 星期五
jQuery UI SPA 應用程式 (四) : 檔案處理函式庫
今天繼續幹活, 目標是整理很久之前寫好的 Javascript 函式庫, 我將其中伺服端部分的程式碼刪除以便用在本次專案上. 由於資安限制不能安裝與使用資料庫, 只好用檔案處理方式來協助作業自動化, 因此檔案處理函式庫在整個專案中扮演關鍵角色.
完整的 files.js 參考 GitHub :
# https://github.com/tony1966/test/blob/master/jqueryui-app/lib/file.js
下面逐一測試這些函數的用法.
範例 9 : 使用 FXO 物件讀取文字檔案
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 主題佈景選擇器 -->
<select id="themes">
<option value="base">base</option>
<option value="black-tie">black-tie</option>
<option value="blitzer">blitzer</option>
<option value="cupertino">cupertino</option>
<option value="dark-hive">dark-hive</option>
<option value="dot-luv">dot-luv</option>
<option value="eggplant">eggplant</option>
<option value="excite-bike">excite-bike</option>
<option value="flick">flick</option>
<option value="hot-sneaks">hot-sneaks</option>
<option value="humanity">humanity</option>
<option value="le-frog">le-frog</option>
<option value="mint-choc">mint-choc</option>
<option value="overcast">overcast</option>
<option value="pepper-grinder">pepper-grinder</option>
<option value="redmond">redmond</option>
<option value="smoothness">smoothness</option>
<option value="south-street">south-street</option>
<option value="start">start</option>
<option value="sunny">sunny</option>
<option value="swanky-purse">swanky-purse</option>
<option value="trontastic">trontastic</option>
<option value="ui-darkness">ui-darkness</option>
<option value="ui-lightness">ui-lightness</option>
<option value="vader">vader</option>
</select>
<script>
$(function(){
$("#themes").selectmenu();
$("#themes").val("hot-sneaks");
$("#themes").selectmenu("refresh");
$('#themes').on('selectmenuchange', function() {
var theme=$(this).val();
var href="jquery/themes/" + theme + "/jquery-ui.min.css";
$("#theme").attr("href", href);
});
});
</script>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<button id="read_file" class="ui-button ui-widget ui-corner-all">讀取檔案</button>
<div id="out1" class="ui-state-highlight ui-corner-all" style="margin-top: 10px; padding: 5px;"></div>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#read_file").click(function(e) {
e.preventDefault();
var folder=get_folder(); //取得此網頁的本機路徑
var txt=read_file(folder + "hello-world.txt"); //讀取 .txt 檔
var htm=read_file(folder + "hello-world.htm"); //讀取 .htm 檔
$("#out1").html(folder + "<br>" + txt + "<br>" + htm);
$("#out1").show();
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
$("#out1").hide();
});
</script>
</body>
</html>
此網頁中的 tab1 頁籤中放置了一個按鈕與預設隱藏的 div 元素 (套用 jQuery UI 的 highlight 樣式類別), 當按下按鈕時會先呼叫 files.js 函式庫中的 get_folder() 函數來取得此網頁在本機中的路徑, 然後呼叫 read_file() 分別讀取專案根目錄下的 hello-world.txt 與 hello-world.htm 這兩個存文字檔案, hello-world.txt 內容為 :
Hello!
World! (text)
而 hello-world.htm 內容為 :
<b>Hello!</b>
<b>World! (html)</b>
將檔案路徑與讀取之檔案內容用跳行元素 br 串接後呼叫 html() 輸出到隱藏的 div 高亮度元件, 最後呼叫 show() 顯示此高亮度元素, 結果如下 :
注意, 由於使用了 Active X 技術, 此範例網頁只能在 IE 執行 (Edge 不支援), 且按下按鈕時會出現如下警告, 必須選 '是' 才會正常執行 :
參考 :
# [Jquery]讓div能自由的show、hide
刪減後的函式庫檔案 file.js 如下所示, 此函式庫使用微軟 ActiveX 技術, 因此只能在 IE 瀏覽器上運作 :
1. 匯入函數 :
此函數用來讀取 js 程式 (函式) 並執行其中的頂層程式碼.
/*-----------------------------------------------------------------------------
include(filename)
功能 :
此函數用來匯入其他外部 Javascript 檔. 僅限於 Client 端之 WSH 應用中.
參數 :
filename : 外部 Javascript 檔名 (字串)
傳回值 :
無/null
範例 :
include("parse.js");
-----------------------------------------------------------------------------*/
function include(filename) {
try {
var FSO=new ActiveXObject ("Scripting.FileSystemObject");
var TXO=FSO.openTextFile(filename,1);
var fileData=TXO.readAll();
eval(fileData); //執行 JS 檔內容
TXO.Close();
TXO = null;
FSO = null;
}
catch (e) {return e.description;}
}
2. 讀取文字檔案 :
函式 read_file() 用來讀取文字檔, 傳回整個檔案內容 (字串); read_lines() 則逐行讀取文字檔, 傳回值為檔案中各行依序組成之陣列.
/*-----------------------------------------------------------------------------
read_file(filename)
功能 :
此函數用來讀取外部文字檔, 結果以字串傳回.
參數 :
filename : 文字檔檔名 (含路徑)
傳回值 :
成功傳回檔案內容字串, 失敗傳回原因字串
範例 :
var fileData=read_file("test.log");
-----------------------------------------------------------------------------*/
function read_file(filename) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
var TXO=FSO.openTextFile(filename,1,false);
var fileData=TXO.readAll();
TXO.Close();
TXO=null;
FSO=null;
return fileData;
}
catch (e) {return e.description;}
}
/*-----------------------------------------------------------------------------
read_lines(filename)
功能 :
此函數用來讀取外部文字檔, 並以分行符號拆分每列後儲存在陣列中傳回.
參數 :
filename : 文字檔檔名 (含路徑)
傳回值 :
成功傳回陣列, 失敗傳回原因
範例 :
var array_lines=read_lines("test.log");
-----------------------------------------------------------------------------*/
function read_lines(filename) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
var TXO=FSO.openTextFile(filename,1,false);
var array_lines=new Array();
while (!TXO.atEndOfStream) {
array_lines.push(TXO.ReadLine()); //讀取每行放入陣列中
}
TXO.Close();
TXO=null;
FSO=null;
return array_lines;
}
catch (e) {return e.description;}
}
3. 寫入文字檔 :
函式 write_file() 將字串以覆蓋或新建方式寫入外部文字檔; append() 是將字串貼附到檔尾; 而prepend() 則是將字串貼附到檔頭.
/*-----------------------------------------------------------------------------
write_file(filename,text)
功能 :
此函數用來將純文字寫入外部文字檔 (覆蓋或新建).
參數 :
filename : 文字檔檔名 (含路徑)
text : 檔案內容
傳回值 :
成功傳回 1, 失敗傳回原因
範例 :
var result=write_file("test.log", "This is a book");
-----------------------------------------------------------------------------*/
function write_file(filename,text) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
var TXO=FSO.openTextFile (filename,2,true); //2=寫入,true=新建
TXO.Write(text); //寫入檔案
TXO.Close();
FSO=null;
return 1;
}
catch(e) {return e.description;}
}
/*-----------------------------------------------------------------------------
append(filename,text)
功能 :
此函數用來將純文字寫入外部文字檔後面(不存在就新建).
參數 :
filename : 文字檔檔名 (含路徑)
text : 檔案內容
傳回值 :
成功傳回 1, 失敗傳回原因字串
範例 :
var result=append("test.log", "This is a book");
-----------------------------------------------------------------------------*/
function append(filename,text) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
var TXO=FSO.openTextFile(filename,8,true); //8=附加,true=新建
TXO.Write(text); //寫入檔案
TXO.Close();
FSO=null;
return 1;
}
catch(e) {return e.description;}
}
/*-----------------------------------------------------------------------------
prepend(filename,text)
功能 :
此函數用來將純文字寫入外部文字檔前面(不存在就新建).
參數 :
filename : 文字檔檔名 (含路徑)
text : 檔案內容
傳回值 :
成功傳回 1, 失敗傳回原因字串
範例 :
var result=prepend("test.log", "This is a book");
-----------------------------------------------------------------------------*/
function prepend(filename,text) {
var new_text=text + read_file(filename); //串接
return write_file(filename,new_text);
}
4. 刪除文字檔部分內容 :
函式 remove_lines() 會刪除文字檔中指定之行數 (0 起始); remove_prelines() 用來刪除文字檔指定之前面幾行; 而 emove_lastlines() 則刪除文字檔指定之最後幾行.
/*-----------------------------------------------------------------------------
remove_lines(filename,lines_array)
功能 :
此函數用來移除文字檔指定之行.
參數 :
filename : 文字檔檔名 (含路徑)
lines_array : 要移除之行數陣列 (0 起算)
傳回值 :
成功傳回 1, 失敗傳回原因字串
範例 :
var result=remove_lines("test.log", [0]);
var result=remove_lines("test.log", [2,4,6]);
-----------------------------------------------------------------------------*/
function remove_lines(filename,lines_array) {
var lines_array=lines_array.sort(); //行號排序,以便取出要刪的最後一行行數
var text=read_lines(filename); //讀取檔案成陣列
var break_point=lines_array[lines_array.length-1] + 1; //斷點
var pre=text.slice(0, break_point); //前半部 (要處理刪除作業)
//剩下的後半部陣列不須處理刪除作業
var left=text.slice(break_point); //選取斷點至陣列尾
var tmp=new Array();
var line_str=lines_array.join(); //把欲刪除行號組成字串
for (var i = 0; i < pre.length; i++) { //沒在刪除名單的放入 tmp 陣列
if (line_str.indexOf(i.toString()) == -1 ) {tmp.push(pre[i]);} //不刪除
else {continue;} //有在刪除名單的不存入 tmp : 刪除
}
tmp=tmp.concat(left); //串接刪除後的前半部與後半部串接
return write_file(filename,tmp.join("\r\n"));
}
/*-----------------------------------------------------------------------------
remove_prelines(filename,numbers)
功能 :
此函數用來移除文字檔最前面指定之行數.
參數 :
filename : 文字檔檔名 (含路徑)
numbers : 移除之行數
傳回值 :
成功傳回 1, 失敗傳回原因字串
範例 :
var result=remove_prelines("test.log", 2);
-----------------------------------------------------------------------------*/
function remove_prelines(filename,numbers) {
var lines=read_lines(filename); //
for (var i = 0; i < numbers; i++) {lines.shift();}
return write_file(filename,lines.join("\r\n"));
}
/*-----------------------------------------------------------------------------
remove_lastlines(filename,numbers)
功能 :
此函數用來移除文字檔最後面指定之行數.
參數 :
filename : 文字檔檔名 (含路徑)
numbers : 移除之行數
傳回值 :
成功傳回 1, 失敗傳回原因字串
範例 :
var result=remove_lastlines("test.log", 2);
-----------------------------------------------------------------------------*/
function remove_lastlines(filename,numbers) {
var lines=read_lines(filename); //讀進檔案為陣列
lines.reverse(); //陣列倒序
for (var i = 0; i < numbers; i++) {lines.shift();} //刪除前面幾列
lines.reverse(); //陣列倒序回去
return write_file(filename,lines.join("\r\n"));
}
5. 檔案目錄資訊 :
函式 get_files() 會以陣列傳回指定目錄下之檔案列表; file_exist() 用來檢查指定之檔案是否存在 (存在傳回 1); delete_file() 用來刪除指定之檔案 (成功傳回 1), get_folder() 則傳回網頁檔所在之本機路徑.
/*-----------------------------------------------------------------------------
get_files(folder)
功能 :
此函數用來取得指定目錄下的檔案列表, 以陣列傳回.
參數 :
folder : 檔案路徑 (注意, 目錄需用兩個倒斜線分隔)
傳回值 :
陣列或失敗原因
範例 :
var files=get_files("my_doc");
var files=get_files("c:\\test\\my_doc");
-----------------------------------------------------------------------------*/
function get_files(folder) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
var folderObj=FSO.GetFolder(folder);
var enumObj=new Enumerator(folderObj.Files);
var filesArray=new Array();
for (;!enumObj.atEnd();enumObj.moveNext()) {
filesArray.push(enumObj.item().Name);
}
folderObj=null;
enumObj=null;
FSO=null;
return filesArray;
}
catch(e) {return e.description;}
}
/*-----------------------------------------------------------------------------
file_exist(file_name)
功能 :
此函數用來檢查檔案是否存在.
參數 :
file_name : 檔案名稱與路徑 (注意, 目錄需用兩個倒斜線分隔)
傳回值 :
成功傳回 1, 失敗傳回原因
範例 :
var result=file_exist("c:\\test\\my_doc.txt");
-----------------------------------------------------------------------------*/
function file_exist(file_name) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
if (FSO.FileExists(file_name)) {return 1;}
else {return 0;}
FSO=null;
}
catch(e) {return e.description;}
}
/*-----------------------------------------------------------------------------
delete_file(file_name)
功能 :
此函數用來刪除檔案.
參數 :
file_name : 檔案名稱與路徑 (注意, 目錄需用兩個倒斜線分隔)
傳回值 :
成功傳回 1, 失敗傳回原因
範例 :
var result=delete_file("c:\\test\\my_doc.txt");
-----------------------------------------------------------------------------*/
function delete_file(file_name) {
try {
var FSO=new ActiveXObject("Scripting.FileSystemObject");
if (FSO.FileExists(file_name)) {FSO.DeleteFile(file_name);}
FSO=null;
return 1;
}
catch(e) {return e.description;}
}
/*-----------------------------------------------------------------------------
get_folder()
功能 :
此函數會傳回網頁檔所在本機路徑, 例如 D:\\project\\pitch\\
參數 :
無
傳回值 : 字串 (雙倒斜線格式 D:\\project\\pitch\\)
-----------------------------------------------------------------------------*/
function get_folder() { //傳回目前網頁所在之目錄字串
//取得目前網頁所在目錄,例如 /D:\project\pitch\pitch.htm
var browser=window.navigator.appName;
var b_version=window.navigator.appVersion;
var version=b_version.split(";");
var trim_Version=version[1].replace(/[ ]/g,"");
//取得目前網頁所在目錄,/D:/project/pitch/pitch.htm
var sys_path=unescape(window.location.pathname);
//去除檔名,從右邊開始找第一個右斜線 / 索引
var pos=sys_path.lastIndexOf("\/");
//須去除第一個右斜線,故從 1 開始直到右側第一個右斜線(含)
var path=sys_path.substring(1,pos+1);
//工作目錄路徑演算結果例如 path=D:/project/pitch/
//製作 FSO 物件運作所需之系統路徑字串 (由單一倒斜線轉成兩個倒斜線)
var path_arr=path.split("\/"); //先拆成陣列
var folder=path_arr.join("\\\\"); //再組合為字串 D:\\project\\pitch\\
return folder;
}
先在專案根目錄下新增一個 lib 資料夾, 將此 file.js 函式庫檔案存放於 /lib 下 :
完整的 files.js 參考 GitHub :
# https://github.com/tony1966/test/blob/master/jqueryui-app/lib/file.js
下面逐一測試這些函數的用法.
範例 9 : 使用 FXO 物件讀取文字檔案
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Single Page Application</title>
<script src="jquery/jquery.js"></script>
<script src="jquery/jquery-ui.js"></script>
<script src="jquery/datatables.js"></script>
<script src="lib/file.js"></script>
<link id="theme" href="jquery/themes/hot-sneaks/jquery-ui.css" rel="stylesheet">
<link href="jquery/datatables.css" rel="stylesheet">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size:10px;
}
</style>
</head>
<body>
<!-- 主題佈景選擇器 -->
<select id="themes">
<option value="base">base</option>
<option value="black-tie">black-tie</option>
<option value="blitzer">blitzer</option>
<option value="cupertino">cupertino</option>
<option value="dark-hive">dark-hive</option>
<option value="dot-luv">dot-luv</option>
<option value="eggplant">eggplant</option>
<option value="excite-bike">excite-bike</option>
<option value="flick">flick</option>
<option value="hot-sneaks">hot-sneaks</option>
<option value="humanity">humanity</option>
<option value="le-frog">le-frog</option>
<option value="mint-choc">mint-choc</option>
<option value="overcast">overcast</option>
<option value="pepper-grinder">pepper-grinder</option>
<option value="redmond">redmond</option>
<option value="smoothness">smoothness</option>
<option value="south-street">south-street</option>
<option value="start">start</option>
<option value="sunny">sunny</option>
<option value="swanky-purse">swanky-purse</option>
<option value="trontastic">trontastic</option>
<option value="ui-darkness">ui-darkness</option>
<option value="ui-lightness">ui-lightness</option>
<option value="vader">vader</option>
</select>
<script>
$(function(){
$("#themes").selectmenu();
$("#themes").val("hot-sneaks");
$("#themes").selectmenu("refresh");
$('#themes').on('selectmenuchange', function() {
var theme=$(this).val();
var href="jquery/themes/" + theme + "/jquery-ui.min.css";
$("#theme").attr("href", href);
});
});
</script>
<!-- 頁嵌面板 -->
<div id="tabs">
<ul>
<li><a href="#tabs-1">tab1</a></li>
<li><a href="#tabs-2">tab2</a></li>
<li><a href="#tabs-3">tab3</a></li>
</ul>
<div id="tabs-1">
<button id="read_file" class="ui-button ui-widget ui-corner-all">讀取檔案</button>
<div id="out1" class="ui-state-highlight ui-corner-all" style="margin-top: 10px; padding: 5px;"></div>
<script>
$(function(){
//監聽按鈕之 click 事件
$("#read_file").click(function(e) {
e.preventDefault();
var folder=get_folder(); //取得此網頁的本機路徑
var txt=read_file(folder + "hello-world.txt"); //讀取 .txt 檔
var htm=read_file(folder + "hello-world.htm"); //讀取 .htm 檔
$("#out1").html(folder + "<br>" + txt + "<br>" + htm);
$("#out1").show();
});
});
</script>
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
<script>
$(function(){
$("#tabs" ).tabs();
$("#out1").hide();
});
</script>
</body>
</html>
此網頁中的 tab1 頁籤中放置了一個按鈕與預設隱藏的 div 元素 (套用 jQuery UI 的 highlight 樣式類別), 當按下按鈕時會先呼叫 files.js 函式庫中的 get_folder() 函數來取得此網頁在本機中的路徑, 然後呼叫 read_file() 分別讀取專案根目錄下的 hello-world.txt 與 hello-world.htm 這兩個存文字檔案, hello-world.txt 內容為 :
Hello!
World! (text)
而 hello-world.htm 內容為 :
<b>Hello!</b>
<b>World! (html)</b>
將檔案路徑與讀取之檔案內容用跳行元素 br 串接後呼叫 html() 輸出到隱藏的 div 高亮度元件, 最後呼叫 show() 顯示此高亮度元素, 結果如下 :
注意, 由於使用了 Active X 技術, 此範例網頁只能在 IE 執行 (Edge 不支援), 且按下按鈕時會出現如下警告, 必須選 '是' 才會正常執行 :
參考 :
# [Jquery]讓div能自由的show、hide
反應: |
訂閱:
文章
(
Atom
)