作者TonyQ (沉默是金。)
看板Ajax
標題Re: [ js ] getElementsByClassName for IE6
時間Sun Jul 11 23:42:12 2010
※ 引述《s25g5d4 (死城盜賊)》之銘言:
: 昨天研究了一下一本書
: 征服javascript
: 對其中的this與函數作用域以及fn.call()很有興趣
: 就寫出了這個函數
其實覺得好像刻意為了寫this跟call多繞了幾圈耶 XD
而且我不太瞭解為什麼要特地弄個this.a,
其實弄成接回傳值就好啦。XD
: if(!document.getElementsByClassName) {
: document.getElementsByClassName=function(classN) { //用運算式創立函數
: var tag=this.firstChild; //this指向document
: this.a=(this==document? [] : null); //每次從外部呼叫函數時
: do{ //清空陣列
: if(tag.hasChildNodes()) {
: document.getElementsByClassName.call(tag,classN);
: /*
: *fn.call(a,arg)將會執行fn()並使fn()的作用域改為a arg則是參數
: *簡單的說就是this將會指向到tag
: */
: }
: if(tag.className==classN)
: document.a.push(tag);
: tag=tag.nextSibling;
: }while(tag);
: return document.a;
: };
: }
我先把 getElementsByClassName 先換個名字,
弄個基礎測試環境是這個板本
http://fiddle.jshell.net/wWhQY/6/
第一個版本,把奇怪的 document.a 換成抓遞迴回傳值
http://fiddle.jshell.net/wWhQY/7/
第二個版本,把難懂的call換掉。(基本上能不用就不用,除非比較直覺)
http://fiddle.jshell.net/wWhQY/8/
第三個版本,把細部的邏輯拆出來,讓主線清楚
http://fiddle.jshell.net/wWhQY/9/
本來想寫第四個版本,除了綁document原生物件,加綁綁 prototype,
這樣可以更像原生的getElementsByClassName
你可以從任意一個 Element 去取 _getElementsByClassName
http://fiddle.jshell.net/wWhQY/10/
不過測了一下,ie6 不支援從 Element加上prototype function,
所以這個版本就變成firefox only了(但firefox又不需要這東西..XD)
: 寫的時候為了document.a搞到焦頭爛額...
: 每次執行都要清除一次 那這樣執行到第六行時因為回呼函數也會被清除...
: 所以只好改用this.a並加入一個判斷式 當this指向document時就清空this.a
: 又因為this指向到document所以此時的this.a等於document.a
: 當執行到第六行時的this就會指向到tag 所以這時候的this.a = tag.a所以給null
: 因為用不到 當變數值指向null時就會被javascript編譯器回收
: 總之就是錯綜複雜 搞到我也亂了XDDDD
: 所以...
: IE6 must die!
其實你會覺得很混亂是因為你沒有把flow抓穩,
而全域變數在遞迴時的操作狀態又更為複雜,
這種遞迴呼叫,把flow抓穩是很重要的事情。:p
用至少一個sample去用腦袋逐行執行到底是必要的。
--
我:一半的日子讓你說,我聽你說你的所有
______________________________________
______________________________________一半的日子我想說,對你說過去的所有:我
_______________________________________________________
在討論中妥善扮演兼具聆聽與分享的角色,是我們一生的課題。
_______________________________________________________
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.70.191.115
→ TonyQ:btw 我覺得fiddle 對firebug不太友善 XD 有人跟我一樣感覺嗎 07/11 23:43
→ TonyQ:或者應該反過來說,firebug對iframe不太友善。:p 07/11 23:43
推 s25g5d4:就是..為了用this與call所以故意寫的@@ 我是覺得用傳值 07/12 00:06
→ s25g5d4:如果有人居心不良的話就爆了@@ 07/12 00:06
→ s25g5d4:一開始的想法就是去抓arguments[1] 07/12 00:07
→ grence:開發還是用firebug,jsFiddle只是為了找個 host..測IE XD 07/12 00:12
→ TonyQ:this/call 一樣可以因為居心不良而爆啊..XD 07/12 00:37
→ TonyQ:再說,其實只要把函式隱藏起來,外面調用不到就很安全.. 07/12 00:38
推 adamp3:fiddle真的滿不錯的啊 07/12 00:41