Javascript best practice and optimization
https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
https://github.com/airbnb/javascript
https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
https://github.com/airbnb/javascript
標籤: javascript
IE與Firefox的CSS兼容大全
作者:AYI 日期:2006-10-25
1.DOCTYPE 影響 CSS 處理
2.FF: div 設置 margin-left, margin-right 為 auto 時已經居中, IE 不行
3.FF: body 設置 text-align 時, div 需要設置 margin: auto(主要是 margin-left,margin-right) 方可居中
4.FF: 設置 padding 後, div 會增加 height 和 width, 但 IE 不會, 故需要用 !important 多設一個 height 和 width
5.FF: 支持 !important, IE 則忽略, 可用 !important 為 FF 特別設置樣式,值得注意的是,一定要將xxxx !important 這句放置在另一句之上
6.div 的垂直居中問題: vertical-align:middle; 將行距增加到和整個DIV一樣高 line-height:200px; 然後插入文字,就垂直居中了。缺點是要控制內容不要換行
7.cursor: pointer 可以同時在 IE FF 中顯示游標手指狀, hand 僅 IE 可以
8.FF: 鏈接加邊框和背景色,需設置 display: block, 同時設置 float: left 保證不換行。參照 menubar, 給 a 和 menubar 設置高度是為了避免底邊顯示錯位, 若不設 height, 可以在 menubar 中插入一個空格。
9.在mozilla firefox和IE中的BOX模型解釋不一致導致相差2px解決方法:div{margin:30px!important;margin:28px;}
注意這兩個margin的順序一定不能寫反,據阿捷的說法!important這個屬性IE不能識別,但別的瀏覽器可以識別。所以在IE下其實解釋成這樣:div{maring:30px;margin:28px}
重複定義的話按照最後一個來執行,所以不可以只寫margin:XXpx!important;
10.IE5 和IE6的BOX解釋不一致
IE5下div{width:300px;margin:0 10px 0 10px;}
div的寬度會被解釋為300px-10px(右填充)-10px(左填充)最終div的寬度為280px,而在IE6和其他瀏覽器上寬度則是以 300px+10px(右填充)+10px(左填充)=320px來計算的。這時我們可以做如下修改div{width:300px! important;width /**/:340px;margin:0 10px 0 10px}
關於這個/**/是什麼我也不太明白,只知道IE5和firefox都支持但IE6不支持,如果有人理解的話,請告訴我一聲,謝了!:)
11.ul標籤在Mozilla中默認是有padding值的,而在IE中只有margin有值所以先定義ul{margin:0;padding:0;}
就能解決大部分問題
注意事項:
1、float的div一定要閉合。
例如:(其中floatA、floatB的屬性已經設置為float:left;)<#div id=\"floatA\" >
<#div id=\"floatB\" >
<#div id=\"NOTfloatC\" >
這裡的NOTfloatC並不希望繼續平移,而是希望往下排。
這段代碼在IE中毫無問題,問題出在FF。原因是NOTfloatC並非float標籤,必須將float標籤閉合。
在<#div class=\"floatB\">
<#div class=\"NOTfloatC\">
之間加上<#div class=\"clear\">
這個div一定要注意聲明位置,一定要放在最恰當的地方,而且必須與兩個具有float屬性的div同級,之間不能存在嵌套關係,否則會產生異常。
並且將clear這種樣式定義為為如下即可:.clear{
clear:both;}
此外,為了讓高度能自動適應,要在wrapper裡面加上overflow:hidden;
當包含float的box的時候,高度自動適應在IE下無效,這時候應該觸發IE的layout私有屬性(萬惡的IE啊!)用zoom:1;可以做到,這樣就達到了兼容。
例如某一個wrapper如下定義:.colwrapper{
overflow:hidden;
zoom:1;
margin:5px auto;}
2、margin加倍的問題。
設置為float的div在ie下設置的margin會加倍。這是一個ie6都存在的bug。
解決方案是在這個div裡面加上display:inline;
例如:
<#div id=\"imfloat\">
相應的css為
#IamFloat{
float:left;
margin:5px;/*IE下理解為10px*/
display:inline;/*IE下再理解為5px*/}
3、關於容器的包涵關係
很多時候,尤其是容器內有平行佈局,例如兩、三個float的div時,寬度很容易出現問題。在IE中,外層的寬度會被內層更寬的div擠破。一定要用Photoshop或者Firework量取像素級的精度。
4、關於高度的問題
如果是動態地添加內容,高度最好不要定義。瀏覽器可以自動伸縮,然而如果是靜態的內容,高度最好定好。(似乎有時候不會自動往下撐開,不知道具體怎麼回事)
5、最狠的手段 - !important;
如果實在沒有辦法解決一些細節問題,可以用這個方法.FF對於"!important"會自動優先解析,然而IE則會忽略.如下.tabd1{
background:url(/res/images/up/tab1.gif) no-repeat 0px 0px !important; /*Style for FF*/
background:url(/res/images/up/tab1.gif) no-repeat 1px 0px; /* Style for IE */}
值得注意的是,一定要將xxxx !important 這句放置在另一句之上,上面已經提過
標籤: css, javascript
轉自:http://ccca.nctu.edu.tw/~hlb/trans/practicalcss/
兩個div並排
<div style="float: left;"></div>
<div style="float: left;"></div>
div置中:
<div style="margin: 0px auto; text-align: center;">
<div style="float: left;"></div>
<div style="float: left;"></div>
</div>
標籤: css, javascript
轉自:www.cnblogs.com/redstar/archive/2007/04/27/729496.aspx
1、瀏覽器事件的捕捉
在IE下有一個全局的window.event,當事件觸發後可以直接使用,但是在fireFox下沒有這個東西,當調用觸發事件調用一個函數時,如果這個函數沒有形參,那麼firefox會默認的把event(事件)傳進去,但是有參數時就不行啦,所以解決的辦法是,自己手動傳一個event進去,這樣就ok了,具體代碼如下:
下面兩個函數,都是響應鼠標onclick時觸發的動作,第一個在ie下使用正常,但是在firefox下卻有問題,改成第二個那樣使用,就沒有問題了,注意調用方法的區別
onclick="testevent(event)"
其實event對像在ie以及firefox還有很多不同的特性,比如clienx,pagex等,但是由於在現在流行使用的js框架 prototype中解決了很多這些問題,所以如果是在基於prototype下的開發,這些問題可以考慮得少一些了,只是上面提到的這個捕獲問題, prototype中並沒有完善的解決,所以單獨列出來,下面提及的關於js的也都只列出prototype中未解決的
2、關於透明度的設置
為了達到給層設置半透明的效果時,在IE和firefox下也有所不同,IE下,style的filter屬性有Alpha值可供使用,而firefox下沒有Alpha值,所以得指定style的MozOpacity,代碼見下:
filter: Alpha(opacity=10); /*IE*/
-moz-opacity:.1; /*老版本FireFox 1.0 以前*/
opacity:0.1; /*新版本FireFox*/
3、定位層時的有趣問題
在定位層時,我們的做法是給層的style.left 和 style.top設置位置,但是今天發現了一個很有趣的問題,代碼如下:
document.getElementById('dialog').left = 100;
document.getElementById('dialog').left = 100;
//問題出現了,在ie下,默認將層的左上角定位在(100px,100px)這個點上
//但是在firefox下卻死活都不行,後來發現,原來ie在你沒有指定單位的時候
//替你加上了單位「px」,而firefox比較「笨」
//他覺得你沒有指定單位,就不給你定位,好了,那麼標準的寫法應該是這樣:
document.getElementById('dialog').left = 100px;
document.getElementById('dialog').left = 100px;
//這樣firefox也認了
//給一個id為dialog的層定位
document.getElementById('dialog').left = 100;
document.getElementById('dialog').left = 100;
//問題出現了,在ie下,默認將層的左上角定位在(100px,100px)這個點上
//但是在firefox下卻死活都不行,後來發現,原來ie在你沒有指定單位的時候
//替你加上了單位「px」,而firefox比較「笨」
//他覺得你沒有指定單位,就不給你定位,好了,那麼標準的寫法應該是這樣:
document.getElementById('dialog').left = 100px;
document.getElementById('dialog').left = 100px;
//這樣firefox也認了
4、PNG透明背景的問題
PNG圖片在網站設計中是不可或缺的部分,最大的特點應該在於PNG可以無損壓縮,而且還可以設置透明,對於增強網站的圖片色彩效果有重要的作用。
但為什麼PNG圖片卻沒有GIF和JPG圖片的使用來得廣泛呢,這個禍因應歸屬於微軟的IE瀏覽器(Firefox和Opera對PNG支持的比較好,而現在瀏覽器的主流IE6卻無法很好的支持)。不過微軟在最近也開始改過自新了,新出的的IE7可以很好的支持PNG,可以想像在未來的網絡世界, PNG圖片的重要性將會更加凸顯。
但在大家還在絕大多數的使用IE6的時候,我們又怎樣在IE6的世界去完美使用PNG圖片呢(PNG圖片的時候最重要的地方在於PNG透明背景圖片的運用)。我們應該慶幸我們是幸福的!IE5.5+的AlphaImageLoader濾鏡為通向png提供了一個道路,如果他載入的是PNG (Portable Network Graphics)格式,則0%-100%的透明度也被提供。但IE5.0無法支持屬性,那只有完全絕望了,不過絕望的只是幾個,得到是絕大數,我們應該知足,知足才會常樂。
現在我們將通過Hack和AlphaImageLoader濾鏡來實現IE6下的PNG透明背景圖片。
先熟悉下濾鏡的語法:
filter : progid:DXImageTransform.Microsoft.AlphaImageLoader ( enabled=bEnabled , sizingMethod=sSize , src="/blog/sURL" )
屬性:
enabled : 可選項。布爾值(Boolean)。設置或檢索濾鏡是否激活。true | false
true : 默認值。濾鏡激活。
false : 濾鏡被禁止。
sizingMethod : 可選項。字符串(String)。設置或檢索濾鏡作用的對象的圖片在對像容器邊界內的顯示方式。
crop : 剪切圖片以適應對像尺寸。
image : 默認值。增大或減小對象的尺寸邊界以適應圖片的尺寸。
scale : 縮放圖片以適應對象的尺寸邊界。
src : 必選項。字符串(String)。使用絕對或相對 url 地址指定背景圖像。假如忽略此參數,濾鏡將不會作用。
filter : progid:DXImageTransform.Microsoft.AlphaImageLoader ( enabled=bEnabled , sizingMethod=sSize , src="/blog/sURL" )
屬性:
enabled : 可選項。布爾值(Boolean)。設置或檢索濾鏡是否激活。true | false
true : 默認值。濾鏡激活。
false : 濾鏡被禁止。
sizingMethod : 可選項。字符串(String)。設置或檢索濾鏡作用的對象的圖片在對像容器邊界內的顯示方式。
crop : 剪切圖片以適應對像尺寸。
image : 默認值。增大或減小對象的尺寸邊界以適應圖片的尺寸。
scale : 縮放圖片以適應對象的尺寸邊界。
src : 必選項。字符串(String)。使用絕對或相對 url 地址指定背景圖像。假如忽略此參數,濾鏡將不會作用。
Firefox、Opera等完全支持PNG透明圖片的瀏覽器也支持子選擇器(>),而IE不識別(包括IE7),所有我們可以通過這來定義Firefox、Opera等瀏覽器中PNG圖片的樣式。如下
//給一個id為infoBox的層設置一個透明背景,背景圖片是down.png,代碼如下
//進行了瀏覽器判斷
if (navigator.appName!="Microsoft Internet Explorer")
{
$('infoBox').style.background="0 url(/blog/down.png') no-repeat";
}
else
{
$('infoBox').style.background="0 none no-repeat";
$('infoBox').style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=scale,src="/blog/down.png'")";
}
//給一個id為infoBox的層設置一個透明背景,背景圖片是down.png,代碼如下
//進行了瀏覽器判斷
if (navigator.appName!="Microsoft Internet Explorer")
{
$('infoBox').style.background="0 url(/blog/down.png') no-repeat";
}
else
{
$('infoBox').style.background="0 none no-repeat";
$('infoBox').style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=scale,src="/blog/down.png'")";
}
不過需要注意的一個地方:
使用AlphaImageLoader 後該區域的超鏈接和按鈕會失效,解決的方法:
對鏈接或按鈕直接設置相對位置,讓它們浮動於濾鏡區域的上面。
這裡有4條經驗:
1、在定義 頁面元素的時候,如果該頁面元素不需要被腳本調用,那麼它就不需要定義其name和id屬性;
2、如果需要定義頁面元素的name,id屬性,那麼避免不同元素的name和id相同;
3、如果沒有特殊需要,盡量讓name和id相同,這主要是為了通用
4、在腳本中,獲得元素時,盡量用document.getElementById("name / id") ,能不使用盡量不使用其他的
下面是收集的一些IE和Firefox的差異:
1. 對像問題
1.1 Form對像
現有問題:
現有代碼這獲得form對像通過document.forms("formName"),這樣使用在IE 能接受,MF 不能。
解決方法:
改用 作為下標運算。改為document.forms["formName"]
備註
上述的改用 作為下標運算中的formName是id而name
1.2 HTML對像
現有問題:
在 IE 中,HTML 對象的 ID 可以作為 document 的下屬對像變量名直接使用。在 MF 中不能。
document.all("itemName")或者document.all("itemId")
解決方法:
使用對像ID作為對像變量名
document.getElementById("itemId")
備註
document.all是IE自定義的方法,所以請大家盡量不使用。
還有一種方式,在IE和MF都可以使用
var f = document.forms["formName "];
var o = f. itemId;
1.3 DIV對像
現有問題:
在 IE 中,DIV對象可以使用ID作為對像變量名直接使用。在 MF 中不能。
DivId.style.display = "none"
解決方法:
document.getElementById("DivId").style.display = "none"
備註
獲得對象的方法不管是不是DIV對象,都使用getElementById方法。參見1.2
1.4 關於frame
現有問題
在 IE中 可以用window.testFrame取得該frame,mf中不行
解決方法
在frame的使用方面MF和IE的最主要的區別是:
如果在frame標籤中書寫了以下屬性:
那麼IE可以通過id或者name訪問這個frame對應的window對像
而mf只可以通過name來訪問這個frame對應的window對像
例如如果上述frame標籤寫在最上層的window裡面的htm裡面,那麼可以這樣訪問
IE: window.top.frameId或者window.top.frameName來訪問這個window對像
MF:只能這樣window.top.frameName來訪問這個window對像
另外,在mf和ie中都可以使用window.top.document.getElementById("frameId")來訪問frame標籤
並且可以通過window.top.document.getElementById("testFrame").src = 'xx.htm'來切換frame的內容
也都可以通過window.top.frameName.location = 'xx.htm'來切換frame的內容
1.5 窗口
現有問題
IE中可以通過showModalDialog和showModelessDialog打開模態和非模態窗口,但是MF不支持。
解決辦法
直接使用window.open(pageURL,name,parameters)方式打開新窗口。
如果需要傳遞參數,可以使用frame或者iframe。
2. 總結
2.1 在JS中定義各種對像變量名時,盡量使用id,避免使用name。
在 IE 中,HTML 對象的 ID 可以作為 document 的下屬對像變量名直接使用。在 MF 中不能,所以在平常使用時請盡量使用id,避免只使用name,而不使用id。
2.2 變量名與某 HTML 對像 id 相同的問題
現有問題
在 MF 中,因為對像 id 不作為 HTML 對象的名稱,所以可以使用與 HTML 對像 id 相同的變量名,IE 中不能。
解決方法
在聲明變量時,一律加上 var ,以避免歧義,這樣在 IE 中亦可正常運行。
此外,最好不要取與 HTML 對像 id 相同的變量名,以減少錯誤。
1. document.form.item 問題
(1)現有問題:
現有代碼中存在許多 document.formName.item("itemName") 這樣的語句,不能在 MF 下運行
(2)解決方法:
改用 document.formName.elements["elementName"]
(3)其它
參見 2
2. 集合類對像問題
(1)現有問題:
現有代碼中許多集合類對像取用時使用 (),IE 能接受,MF 不能。
(2)解決方法:
改用 [] 作為下標運算。如:document.forms("formName") 改為 document.forms["formName"]。
又如:document.getElementsByName("inputName")(1) 改為 document.getElementsByName("inputName")[1]
3. window.event
(1)現有問題:
使用 window.event 無法在 MF 上運行
(2)解決方法:
MF 的 event 只能在事件發生的現場使用,此問題暫無法解決。可以這樣變通:
原代碼(可在IE中運行):
>input name="someButton" value="提交" onclick="javascript:gotoSubmit()" type="button"<
...
function gotoSubmit() {
...
alert(window.event); // use window.event
...
}
新代碼(可在IE和MF中運行):
>input name="someButton" value="提交" onclick="javascript:gotoSubmit(event)" type="button"<
...
function gotoSubmit(evt) {
evt = evt ? evt : (window.event ? window.event : null);
...
alert(evt); // use evt
...
}
此外,如果新代碼中第一行不改,與老代碼一樣的話(即 gotoSubmit 調用沒有給參數),則仍然只能在IE中運行,但不會出錯。所以,這種方案 tpl 部分仍與老代碼兼容。
4. HTML 對象的 id 作為對像名的問題
(1)現有問題
在 IE 中,HTML 對象的 ID 可以作為 document 的下屬對像變量名直接使用。在 MF 中不能。
(2)解決方法
用 getElementById("idName") 代替 idName 作為對像變量使用。
5. 用idName字符串取得對象的問題
(1)現有問題
在IE中,利用 eval(idName) 可以取得 id 為 idName 的 HTML 對象,在MF 中不能。
(2)解決方法
用 getElementById(idName) 代替 eval(idName)。
6. 變量名與某 HTML 對像 id 相同的問題
(1)現有問題
在 MF 中,因為對像 id 不作為 HTML 對象的名稱,所以可以使用與 HTML 對像 id 相同的變量名,IE 中不能。
(2)解決方法
在聲明變量時,一律加上 var ,以避免歧義,這樣在 IE 中亦可正常運行。
此外,最好不要取與 HTML 對像 id 相同的變量名,以減少錯誤。
(3)其它
參見 問題4
7. event.x 與 event.y 問題
(1)現有問題
在IE 中,event 對像有 x, y 屬性,MF中沒有。
(2)解決方法
在MF中,與event.x 等效的是 event.pageX。但event.pageX IE中沒有。
故採用 event.clientX 代替 event.x。在IE 中也有這個變量。
event.clientX 與 event.pageX 有微妙的差別(當整個頁面有滾動條的時候),不過大多數時候是等效的。
如果要完全一樣,可以稍麻煩些:
mX = event.x ? event.x : event.pageX;
然後用 mX 代替 event.x
(3)其它
event.layerX 在 IE 與 MF 中都有,具體意義有無差別尚未試驗。
8. 關於frame
(1)現有問題
在 IE中 可以用window.testFrame取得該frame,mf中不行
(2)解決方法
在frame的使用方面mf和ie的最主要的區別是:
如果在frame標籤中書寫了以下屬性:
>frame src="xx.htm" id="frameId" name="frameName"< 那麼ie可以通過id或者name訪問這個frame對應的window對像 而mf只可以通過name來訪問這個frame對應的window對像 例如如果上述frame標籤寫在最上層的window裡面的htm裡面,那麼可以這樣訪問 ie: window.top.frameId或者window.top.frameName來訪問這個window對像 mf: 只能這樣window.top.frameName來訪問這個window對像 另外,在mf和ie中都可以使用window.top.document.getElementById("frameId")來訪問frame標籤 並且可以通過window.top.document.getElementById("testFrame").src = 『xx.htm』來切換frame的內容 也都可以通過window.top.frameName.location = 『xx.htm』來切換frame的內容 關於frame和window的描述可以參見bbs的『window與frame』文章 以及/test/js/test_frame/目錄下面的測試 ----adun 2004.12.09修改 9. 在mf中,自己定義的屬性必須getAttribute()取得 10.在mf中沒有 parentElement parement.children 而用parentNode parentNode.childNodes childNodes的下標的含義在IE和MF中不同,MF使用DOM規範,childNodes中會插入空白文本節點。 一般可以通過node.getElementsByTagName()來迴避這個問題。 當html中節點缺失時,IE和MF對parentNode的解釋不同,例如 form>
table>
input/>
/table>
/form>
MF中input.parentNode的值為form, 而IE中input.parentNode的值為空節點
MF中節點沒有removeNode方法,必須使用如下方法 node.parentNode.removeChild(node)
11.const 問題
(1)現有問題:
在 IE 中不能使用 const 關鍵字。如 const constVar = 32; 在IE中這是語法錯誤。
(2)解決方法:
不使用 const ,以 var 代替。
12. body 對像
MF的body在body標籤沒有被瀏覽器完全讀入之前就存在,而IE則必須在body完全被讀入之後才存在
13. url encoding
在js中如果書寫url就直接寫&不要寫&amp;例如var url = 『xx.jsp?objectName=xx&objectEvent=xxx』;
frm.action = url那麼很有可能url不會被正常顯示以至於參數沒有正確的傳到服務器
一般會服務器報錯參數沒有找到
當然如果是在tpl中例外,因為tpl中符合xml規範,要求&書寫為&
一般MF無法識別js中的&
14. nodeName 和 tagName 問題
(1)現有問題:
在MF中,所有節點均有 nodeName 值,但 textNode 沒有 tagName 值。在 IE 中,nodeName 的使用好像
有問題(具體情況沒有測試,但我的IE已經死了好幾次)。
(2)解決方法:
使用 tagName,但應檢測其是否為空。
15. 元素屬性
IE下 input.type屬性為只讀,但是MF下可以修改
16.比如td.setAttribute("colspan","3");在mf中好用,在ie裡不好用
必須是td.setAttribute("colSpan","3");這樣ie和mf裡都好用
標籤: javascript
一直以來關於AJAX的介紹都很直接簡單,
IBM 這裏一系列文章介紹得比較深入
http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=Mastering+Ajax
但如果有關於AJAX的API Manual就更好了
標籤: IT knowledge, javascript
轉載自:http://ihower.idv.tw/blog/archives/1604
要達到 unobtrusive JavaScript (最新譯名: 不亂入JavaScript) 的境界,就必須對 Event-Driven 有深入的認識,這章對 Events 議題做了很詳盡的解說,前一陣子看YUI Event的時候,裡面提到的兩個IE fix都不太了解緣由,看過這章之後就恍然大悟啦。
相對於 W3C DOM 跟 XMLHttpRequest,Events有更多的 Browser Wars 留下來的問題,有著 Microsoft 蓄意的不相容問題,你必須注意這些實做差異,有些解法甚至有些 tricky,而且必須 case by case,沒有泛用型的偵測法則,例如沒有簡單的 if (W3C model) {.. } else if ( Microsoft model ) { … } 可以用。
Events 可分成三種類型 1. 滑鼠事件 mouse 2. 鍵盤事件 keyboard 3. 界面事件 interface events (例如 form submit,readystatechange等)
click是唯一自動有 accessible 的mouse event,因為當鍵盤 focus 且按 Enter 時也會觸發。而其它mouse events必須手動再加對應的keyboard events,例如 mouseover 等同於 focus,mouseout等於blurred,但有些對應就難了,例如 mousemove (滑鼠移動一個1px就觸發一個事件,但要對應鍵盤就不行了)。因此在 DOM Scripting 這本書也建議(p.111),設了 onclick 的就不要設定 onkeypress event了,因為 click 除了滑鼠,鍵盤也會有作用,多設 onkeypress 反而可能會有新麻煩。
另外一個 keyboard 的 accessability 重點是,可以被 keyboard focus 的元素只有 links,form fields,buttons 這四樣,這是個需要注意的事情,任何 keyboard-frientld event 或 script 都必須設定在這三種元素上面,例如在寫 mouseover 的鍵盤等價方案的時候,畢竟要可以被使用者按 tab 移動到,寫 event script 才有用…:p
Event-handler 註冊的四種方法:
inline ,例如直接在element中寫 onclick=”test()”
traditional model,例如 x.onclick= test
W3C model ,例如 x.addEventListener(’click’,test,false) 或移除 x.removeEventListener(’click’,test,false)
Microsoft model,例如 x.attachEvent(’onclick’,test) 或移除 x.detachEvent(’onclick’,test)
要為後兩者做一個跨瀏覽器的解法並不難,object detection 一下即可。
法一是 JavaScript亂入,不要用。
法二 traditional model 的問題是,無法連續為 x 掛載不同的事件,例如 x.onclick = test; x.onclick = test2 就只剩下 test2 了。因此需要再寫一個 function 包起來,如 x.onclick = function () { test(); test2(); },比較不彈性一點,但如果你可以完整掌握 page 到底有哪些 script,作者建議你可以用 traditional model。
法三法四比較先進(?)是用 事件掛載的方式,讓各個 script 都不會互相影響到。不過有趣的是竟然無法得知 x 已經掛載多少 event handlers,而如果不知道掛載了什麼,就無法移除。
接著是 W3C model 和 Microsoft model 的兩個重大差異,Microsoft model 不支援 event capturing,只有 bubbling(請參考 O3noBLOG addEventListener的第三個參數 ) 。另外就是 Microsoft model 把 event-handler function 當成一般 global function 來處理,也就是如果你用法四 attachEvent 來註冊事件時, event handler裡面的 this 指的是 window 而非發生事件的 object。(作者推薦 Dean Edward’s solution 可以fix)
event bubbling 能有什麼功效? 你可以非常有效率的只設定一個event handler到一個HTML element,然後就可以處理那個element裡面一整群的element,因為它會 bubbling 上去觸發。例如作者的 Usable Forms 的範例中,有132個 form fields,他不想每個都給他加上 event hander,這時就可以利用 event bubbling 在 document 加上 click event 即可,觸發任一個field都會 bubbling 上去到 document,然後在 event handler 中再來根據被觸發的 element 來決定做什麼動作。
在 event handler中,瀏覽器會自動產生一個 event object,W3C model 是根據第一個參數,Microsoft 則總是window.event,因此程式是
document.onclick = handleEvent;
function handleEvent(e) {
var evt = e || window.event;
var evtTarget = evt.target || evt.srcElement;
}
這個 event object 包含了觸發這個事件的 event type (即mouseover 或 keypress 等等)、觸發的 target element ( W3C叫 target, Microsoft叫 srcElement)、觸發時的滑鼠位置(跨瀏覽器處理很複雜,作者不建議去用。而且大部分的情況可以改用你觸發的element的相對位置來解決,第 九章會詳述)、觸發時按下的滑鼠button跟鍵盤button 等等資訊。
注意到觸發事件的element跟 當初被定義 event handler 的 element 並不一定相同 (因為event bubbling),因此 target element 並不一定等於 this。在 traditional跟W3C model中,this 指被定義event handler的 element。但如前所述,微軟的 this 指成 window,也就是如果你有用微軟 attachEvent 這個 this 等於沒什麼用。
看樣子用 evtTarget 好像比較好? 不過瀏覽器對於到底是 “哪個element” 觸發也有不同看法!! 所以尤其是碰到 mouseover,mouseout 你必須特別check抓到的 element是你要的。
所以結論是到底用那種啦? (跨平台 event 果然難搞) 如果你不用Microsoft model的 addEvent的話,而且要被觸發的element跟被定義的element是同一個的話 (不玩event bubbling),那作者推薦用 this 吧。
注意到在DOM Scripting那本書中,Event-handler 完全使用 traditional model 法,也沒有用 event bubbling 進階手法,因此他的 this 一律就是 target element。
最後提一下 Yahoo! UI Library: Event,裡面的 Automatic Event Object Browser Abstraction 跟 Automatic Scope Correction 就是修正那兩個問題。
標籤: javascript
IE冇naturalHeight同naturalWidth : (
solution:
o係img個onload function 手動assign naturalWidth = width
標籤: javascript
Type轉換:
float parseFloat(var)
int parseInt(var)
string b.toString(radix)
string float.toExponential(decimal places) - exponential expression
string float.toFixed(decimal places) - normal expression
string number.toPrecision(significant places) - exponential expression
其他:
eval(string code) - execute the string
string escape(string) - URI encode
string unescape(string) - URI decode
標籤: javascript