[web] 取得指定網(wǎng)頁(yè)節(jié)點(diǎn)的方法歸納——lujjjh
要討論這個(gè)問(wèn)題,我們得先明白什么是網(wǎng)頁(yè)節(jié)點(diǎn)。我們平時(shí)瀏覽網(wǎng)頁(yè)的時(shí)候一般是不會(huì)注意網(wǎng)頁(yè)節(jié)點(diǎn)的,因?yàn)榫W(wǎng)頁(yè)節(jié)點(diǎn)這個(gè)概念是相對(duì)于網(wǎng)頁(yè)源代碼而言的。我們?cè)诰W(wǎng)頁(yè)頁(yè)面上右鍵,選擇查看源代碼即可查看網(wǎng)頁(yè)的源代碼。
我們可以看到網(wǎng)頁(yè)的源代碼的格式與 xml 格式極為相似,也是由一個(gè)一個(gè)節(jié)點(diǎn)構(gòu)成,具體節(jié)點(diǎn)的含義可以看一下百度百科的解釋:
http://baike.baidu.com/view/47398.htm#2
我們要使用 web.form 庫(kù)對(duì)網(wǎng)頁(yè)進(jìn)行操作,首先要取得想要操作的那個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)。若是第一步就出了問(wèn)題,后續(xù)的操作就無(wú)法正常進(jìn)行了。于是,怎樣取得指定的網(wǎng)頁(yè)節(jié)點(diǎn)成了一個(gè)至關(guān)重要的問(wèn)題。在這里,我簡(jiǎn)單的列舉一些常用的方式(以下的 wb 變量均為 web.form 的一個(gè)實(shí)例對(duì)象):
1、通過(guò)節(jié)點(diǎn)的 id 或者 name 一步取得
我們一定非常熟悉 wb.getEle 這個(gè)東西,因?yàn)楂@取元素我們一般都會(huì)調(diào)用這個(gè)方法。我們可以看一下它的函數(shù)原型:
ele = wb.getEle( HTML節(jié)點(diǎn)的ID名name, 框架名 )當(dāng)提供 id 或 name 可以唯一確定一個(gè)節(jié)點(diǎn)的時(shí)候,我們只要提供網(wǎng)頁(yè)節(jié)點(diǎn)的 id 或者 name 屬性,即可獲取該節(jié)點(diǎn)。
當(dāng)網(wǎng)頁(yè)中存在同 name 節(jié)點(diǎn)的時(shí)候,我們則可以用 wb.getEles 方法取得,我們可以看一下它的函數(shù)原型:
tele = wb.getEles( HTML節(jié)點(diǎn)的name屬性, 框架名 )可能這個(gè)方法大家并不常用,wb.getEles 返回的是節(jié)點(diǎn)的集合。因?yàn)榫W(wǎng)頁(yè)中節(jié)點(diǎn)的 id 屬性是不可重復(fù)的,而 name 屬性卻是可重復(fù)的,因此當(dāng)我們想要獲取的節(jié)點(diǎn)有 name 屬性的時(shí)候,就要考慮到網(wǎng)頁(yè)中是否有其他節(jié)點(diǎn)與之 name 屬性相同。wb.getEles 就可以獲取所有指定 name 屬性的節(jié)點(diǎn)。
舉個(gè)例子,網(wǎng)頁(yè)代碼如下:
<html>
<head>
...
</head>
<body>
<input type="checkbox" name="hobbies" value="足球" />
<input type="checkbox" name="hobbies" value="籃球" />
<input type="checkbox" name="hobbies" value="排球" />
</body>
</html>
我們可以發(fā)現(xiàn)我們用 wb.getEle("hobbies") 的話,只能取到足球的 checkbox,而不能取到籃球或排球的節(jié)點(diǎn)。這時(shí)候,我們就可以使用 wb.getEles 來(lái)解決了,代碼如下:
var tele = wb.getEles("hobbies");
var 足球, 籃球, 排球 = tele(0), tele(1), tele(2);
排球.checked = true;
上面一段代碼就可以實(shí)現(xiàn)獲取足球、籃球和排球三個(gè)節(jié)點(diǎn)了,這里要注意的是,wb.getEles 返回的是 com 數(shù)組,因此必須使用小括號(hào)來(lái)讀取數(shù)組成員,而不是中括號(hào),并且 com 數(shù)組的索引是從 0 開(kāi)始的,而不是 1。
2、通過(guò)子節(jié)點(diǎn)取得父節(jié)點(diǎn)
這也是一個(gè)可以被接受的方式。往往我們要直接取得指定的節(jié)點(diǎn)十分困難,但是我們發(fā)現(xiàn)這個(gè)節(jié)點(diǎn)的某一個(gè)子節(jié)點(diǎn)很容易取得。這時(shí)候,我們就可以通過(guò)這個(gè)子節(jié)點(diǎn)來(lái)取得我們想要的父節(jié)點(diǎn)。
舉個(gè)例子,網(wǎng)頁(yè)代碼如下:
...
<form action="..." method="post">
<input type="text" name="username" id="username" />
</form>
...
假設(shè)我們要提交這個(gè)表單,你會(huì)使用什么方法取得表單節(jié)點(diǎn)?或許你會(huì)說(shuō):“這個(gè)表單沒(méi)有 name,也沒(méi)有 id,大概只能枚舉法或者通過(guò)節(jié)點(diǎn)名取得。不過(guò)它里面有一個(gè) input 節(jié)點(diǎn)挺好獲取的?!?br>
枚舉法或者通過(guò)節(jié)點(diǎn)名取節(jié)點(diǎn)確實(shí)是一個(gè)辦法,但是,當(dāng)這個(gè)節(jié)點(diǎn)下某一個(gè)子節(jié)點(diǎn)非常好取的時(shí)候,我們不妨就通過(guò)這個(gè)子節(jié)點(diǎn)搭橋,代碼如下:
var childEle = wb.getEle("username"); // 我們?nèi)〉昧俗庸?jié)點(diǎn)
var ele = childEle.parentNode; // 子節(jié)點(diǎn)的 parentNode 即為我們要取的父節(jié)點(diǎn)
這確實(shí)是一個(gè)好方法,但是你可能會(huì)說(shuō):“我根本不知道什么 parentNode 屬性,幫助文檔里好像也沒(méi)有提及?!?br>
但是你別忘了,我們還有智能提示,即使沒(méi)有智能提示也還有 DOM 幫助手冊(cè),畢竟這是 IE 的東西,不管快手什么事,快手只需要調(diào)用 IE 提供的接口就可以了。因此還有許多智能提示以及幫助中沒(méi)有提及的屬性和方法,我們將會(huì)盡可能多的讓大家了解。
那么,我考大家一個(gè)問(wèn)題,若是網(wǎng)頁(yè)代碼如下,怎么獲取表單節(jié)點(diǎn)呢?
...
<form action="..." method="post">
<div>
<span>
<input type="text" name="username" id="username" />
</span>
</div>
</form>
...
你也許會(huì)說(shuō):“這還不簡(jiǎn)單?同上,childEle.parentNode.parentNode.parentNode...”
噢,這確實(shí)可行,但是當(dāng)父節(jié)點(diǎn)層次非常多的時(shí)候,我們可以有簡(jiǎn)便的方法:
var ele = childEle.form;
childEle.form 可以直接獲取 childEle 所在的表單節(jié)點(diǎn)。是不是感覺(jué)被騙了?呵呵。不,我上面講的那么多并不是廢話,因?yàn)橛袝r(shí)候我們要獲取父節(jié)點(diǎn)并不一定是一個(gè)表單,可能是其他類型的節(jié)點(diǎn),這時(shí)候我們就不得不用 parentNode 了。
3、通過(guò)節(jié)點(diǎn)名取得節(jié)點(diǎn)集合
我們知道,凡是網(wǎng)頁(yè)節(jié)點(diǎn)都有一個(gè)節(jié)點(diǎn)名。那么,我們能不能通過(guò)網(wǎng)頁(yè)節(jié)點(diǎn)名來(lái)獲取網(wǎng)頁(yè)節(jié)點(diǎn)呢?答案當(dāng)然是肯定的。
節(jié)點(diǎn)名類似于節(jié)點(diǎn)的 name 屬性,是可以重復(fù)的,而且由于這些節(jié)點(diǎn)名是固定的,幾乎沒(méi)有哪一個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)名沒(méi)有重復(fù),因此取回的同樣是節(jié)點(diǎn)的集合——一個(gè) com 數(shù)組。
要通過(guò)節(jié)點(diǎn)名獲取節(jié)點(diǎn),可以使用 getElementsByTagName,同樣通過(guò)一個(gè)例子說(shuō)明問(wèn)題,網(wǎng)頁(yè)代碼如下:
...
<img src="..." alt="確定" />
<img src="..." alt="取消" />
...
倘若整張網(wǎng)頁(yè)只有這兩個(gè) img 節(jié)點(diǎn),我們可以使用如下代碼來(lái)獲取這兩個(gè)節(jié)點(diǎn):
var tele = wb.document.getElementsByTagName("img");
var 確定, 取消 = tele(0), tele(1);
取消.click();
在這里我就不多做解釋,想必大家要是沒(méi)有忘記上面的“通過(guò) name 屬性獲取節(jié)點(diǎn)”的話,應(yīng)該很容易能夠理解。
至于第三行,我這里簡(jiǎn)單解釋一下,我們看到網(wǎng)頁(yè)代碼中,兩個(gè) img 節(jié)點(diǎn)都有 onclick 屬性,這個(gè)屬性是指定該節(jié)點(diǎn)被單擊時(shí)觸發(fā)的腳本。
我們通過(guò) 取消.click() 可以觸發(fā)這個(gè)腳本,也就相當(dāng)于我們單擊了取消按鈕。
同樣的,任何節(jié)點(diǎn)都有 getElementsByTagName 函數(shù),我們可以結(jié)合上面的方法來(lái)獲取指定的節(jié)點(diǎn)。
舉個(gè)例子,網(wǎng)頁(yè)代碼如下:
...
<img alt="" />
<!--前面有許多圖片-->
<form action="..." method="post">
<input type="text" name="username" id="username" />
<img src="..." alt="確定" />
<img src="..." alt="取消" />
</form>
...
我們要實(shí)現(xiàn)填完 username 之后,單擊確定按鈕,則可以使用如下代碼:
/*
取的用戶名節(jié)點(diǎn),這里也可以使用 getEle 方法,但是 getEle 方法是 web.form 庫(kù)的一個(gè)封裝方法,
該方法并不能在網(wǎng)頁(yè)節(jié)點(diǎn)上使用。譬如 form 是一個(gè)表單元素,我們要獲取一個(gè)在 form 下的有 id 的
子元素,則只能使用 form.getElementById("ID"),而不能使用 form.getEle("ID")。
而 form.getEle("Name") 則可以用 form.getElementsByName("Name")(0) 替代。具體可看庫(kù)代碼。
*/
var username = wb.document.getElementById("username");
var form = username.form;
var img = form.getElementsByTagName("img")(0); // form 下第一個(gè) img 的節(jié)點(diǎn)(確定),0 替換為 1 可取得第二個(gè)(取消)
img.click();
怎么樣?是不是有些明白了?
4、枚舉法 + 節(jié)點(diǎn)特點(diǎn)
當(dāng)我們想要獲取的節(jié)點(diǎn)沒(méi)有 name,也沒(méi)有 id。甚至用上面的任何方法都難以獲取的時(shí)候該怎么辦呢?當(dāng)我們實(shí)在沒(méi)有辦法的時(shí)候,可以使用枚舉法。但是有一點(diǎn)必須確定,這個(gè)節(jié)點(diǎn)應(yīng)當(dāng)是有特征的。
何為有特征?一般的節(jié)點(diǎn)都有自己的特點(diǎn),比如說(shuō):在一個(gè) form 中有一個(gè) input 節(jié)點(diǎn),其 type 屬性為 "image",而且我們通過(guò)這兩個(gè)線索可以唯一確定這個(gè)節(jié)點(diǎn)。我們就可以遍歷表單中所有的 input 節(jié)點(diǎn),然后再檢查這些節(jié)點(diǎn)的 type 屬性值。
同樣舉個(gè)例子,網(wǎng)頁(yè)代碼如下:
<form id="frmLogin" action="..." method="post">
<input type="text" name="..." />
<input type="text" name="..." />
<input type="text" name="..." />
<input type="image" />
</form>
沒(méi)錯(cuò),我們就要獲取那個(gè) type="image" 的 input 節(jié)點(diǎn)。還記得嗎?我們可以通過(guò) getElementsByTagName 取得所有 input 節(jié)點(diǎn)的。如果你還記得,那就跟我一起做:
var form = wb.getEle("frmLogin"); // 先取得表單節(jié)點(diǎn),這一步很方便
var inputs = form.getElementsByTagName("input"); // 看,這句就獲取了所有的 input 節(jié)點(diǎn)了
嗯,我們已經(jīng)完成了大部分了,取得了表單下所有的 input 節(jié)點(diǎn)的集合,下面我們可以通過(guò) com 庫(kù)來(lái)遍歷這些節(jié)點(diǎn),當(dāng)我們輸入 com.each 的時(shí)候,快手會(huì)自動(dòng)生成循環(huán)體基本代碼,真是太方便了:
var img; // 時(shí)刻準(zhǔn)備被賦值
for index,obj in com.each(inputs) {
// 現(xiàn)在 obj 就是每一個(gè) input 節(jié)點(diǎn)了,有幾個(gè) input,就會(huì)循環(huán)幾次
if (string.lower(obj.type) == "image") { // 判斷 obj 的 type 屬性是否為 image,可以先轉(zhuǎn)化為小寫,寫得嚴(yán)密一些
// 很激動(dòng),現(xiàn)在 obj 就是我們要找的節(jié)點(diǎn)了,我們可以把它賦給 img 變量
img = obj;
break; // 趕緊挑出循環(huán),不要浪費(fèi)系統(tǒng)資源和用戶的時(shí)間
}
}
if (img != null) { // 如果 img 不為空,即我們?nèi)〉搅诉@個(gè)節(jié)點(diǎn)
// 后續(xù)操作,點(diǎn)它!
img.click();
}
怎么樣,是不是很方便呢?趕緊試試看吧。
以上就是我歸納總結(jié)的一些取節(jié)點(diǎn)的方法,希望對(duì)大家有所幫助。如果你是新手,我希望你不要收藏這個(gè)網(wǎng)址。我不希望你一碰到要取節(jié)點(diǎn)就回來(lái)復(fù)制、粘貼,不如現(xiàn)在按照上面的方法好好實(shí)踐操作一下,這些代碼如果你一行一行打上去,絕對(duì)是有深刻的印象的。況且快手有智能提示,函數(shù)名記個(gè)大概即可。
作者: 手快心慢
時(shí)間: 2011-9-19 21:19
本帖最后由 手快心慢 于 2011-9-19 21:19 編輯 補(bǔ)充兩個(gè)方法:
1、無(wú)比強(qiáng)大的 wb.queryEles() 函數(shù)
http://www.aau.cn/thread-2490-1-1.html2、任何一個(gè)節(jié)點(diǎn),都有一個(gè)唯一的uniqueID,
這個(gè)uniqueID可以作為wb.getEle()的參數(shù),所以不存在沒(méi)有ID取不到節(jié)點(diǎn)的問(wèn)題。
使用: “
快手工具->探測(cè)器->網(wǎng)頁(yè)探測(cè)器(webspy)”在生成代碼時(shí),如果可以分別屬性就會(huì)使用wb.queryEles() 函數(shù),否則讀取uniqueID,使用wb.getEle()函數(shù)。