標籤:
JS <noscript>標籤 早期瀏覽器都面臨一個特殊的問題,即當瀏覽器不支援JavaScript 時如何讓頁面平穩地退化。對這個問題的最終解決方案就是創造一個<noscript>元素,用以在不支援JavaScript 的瀏覽器中顯示替代的內容。這個元素可以包含能夠出現在文檔<body>中的任何HTML 元素一一<script>元素除外。
包含在<noscript>元素中的內容只有在下列情況下才會顯示出來:
- 瀏覽器不支援指令碼;
- 瀏覽器支援指令碼,但指令碼被禁用。
符合上述任何一個條件,瀏覽器都會顯示<noscript>中的內容。而在除此之外的其他情況下,瀏覽器不會呈現<noscript> 中的內容。
請著下面這個簡單的例子:
<html><head><tit1e>Exarnp1e HTML Page</tit1e><script type="text/javascript" defer="defer" src="example1. js">< /script><script type="text/javascript" defer="defer" src="example2. js">< /script></head><body><noscript><p>本頁面需要瀏覽器支援(啟用)JavaScript。</noscript></body></html>
這個頁面會在指令碼無效的情況下向使用者顯示一條訊息,而在啟用了指令碼的瀏覽器中,使用者永遠也不會看到它一一儘管它是頁面的一部分。
注意:現代瀏覽器都對JavaScript進行了支援,一般是在使用者的瀏覽器禁用了指令碼的情況下才會顯示<noscript>的內容。
不推薦使用的嵌入JS指令碼的文法
在最早引入<script>元素的時候,該元素與傳統HTML的解析規則是有衝突的。由於要對這個元素應用特殊的解析規則,因此在那些不支援JavaScript 的瀏覽器一一最典型的是Mosaic-一一中就會導致問題。具體來說,不支援JavaScript的瀏覽幫會把<script>元素的內容直接輸出到頁面中,因而會破壞頁面的布局和外觀。
<script><!--function sayHi(){alert ("Hi! " ) ;--></script>
Netscape與Mosaic協商並提出了一個解決方案,讓不支援<script>元素的瀏覽器能夠隱藏嵌入的JavaScript 代碼。這個方案就是把JavaScript 程式碼封裝含在一個HTML 注釋中, 像下面這樣:
給指令碼加上HTML注釋後, Mosaic 等瀏覽器就會忽略<script>標籤中的內容,而那些支援JavaScript 的瀏覽器在遇到這種情況時,則必須進一步確認其中是否包含需要解析的JavaScript 代碼。
雖然這種注釋JavaScript 代碼的格式得到了所有瀏覽器的認可,也能被正確解釋,但由於所有的現代瀏覽器都已經支援JavaScript ,因此也就沒有必要再使用這種格式了。
JS事件(Event)相容性探究
事件(Event)即為使用者的動作,例如:使用者點擊滑鼠,產生onclick事件;按下鍵盤,產生onkeyDown事件;改變輸入框的值,產生onchange事件...
W3C標準規定,事件是作為函數的參數傳入的,例如:
<p id="demo">點擊我將獲得螢幕座標</p>
document.getElementById("demo").onclick=function(e)
{
alert(e.screenX);
}
當在元素上點擊時,彈出警告框,內容為滑鼠在螢幕上的橫座標。這裡函數傳入的參數e,就是事件,瀏覽器會即時跟蹤使用者的行為,如e.screenX、e.screenY、e.offsetX、e.offsetY...
這種做法在FireFox、Chrome、Safari等遵循W3C規範的瀏覽器下是沒有問題的,唯獨在IE(暫時僅限於8.0以下版本,8.0以上版本筆者未曾測試)下是行不通的,IE採用了一種非標準的方式,並不是將事件作為函數參數傳入,而是將事件作為window對象的event屬性:window.event、window.event.screenX...
所以,我們在寫代碼的時候要照顧到IE,做好事件的相容。
下面是筆者給出的一個簡單的相容樣本,該樣本並沒有去判斷瀏覽器,僅僅使用了一個小技巧。
<p id="demo">點擊我將獲得螢幕座標</p>
document.getElementById("demo").onclick=function(e)
{
var e=e||event;
alert(e.screenX);
}
注意,不要將var e=e||event; 寫成 var e=event||e; ,這在FireFox下會提示錯誤,FireFox無法處理未聲明未賦值的變數event。
這裡大家可能有疑慮,為什麼是var e=e||event; ,為什麼是 或運算(||),這樣的結果只能是e=true或者e=false?
筆者告訴大家,在大多數程式設計語言裡,或運算(||)返回的並不只是true或者false,而是返回第一個不為false的變數的值, 例如:
var a=5||6; //a=5
var b=0||5; //b=5
var c=false||"www.itxueyuan.com"; //c="www.itxueyuan.com"
var e=e||event; //e為使用者事件
好,這幾個例子,筆者相信大家一定明白了,上面對事件相容的巧妙處理,也就迎刃而解了。
IT學院提醒,大家在處理瀏覽器安全色問題的時候,盡量不要去判斷瀏覽器,那將會為向後相容帶來風險,或許某個升級的版本開始遵循W3C標準,我們之前寫的代碼在該版本上就會產生錯誤,得不到預想結果。
例如,某個升級的IE版本支援將事件作為函數參數傳入,拋棄了將事件作為window的屬性,而我們的代碼,恰恰是這個樣子的:
if( (/ie/i).test(navigator.userAgent) )
document.getElementById("demo").onclick=function()
{ Javascript addEventListener和attachEvent的區別
alert(window.event.screenX);
}
else
document.getElementById("demo").onclick=function(e)
{
alert(e.screenX);
}
那麼在升級的IE瀏覽器上運行就會產生錯誤了。
最後,梳理了思路,再把上面的代碼重複一遍。
<p id="demo">點擊我將獲得螢幕座標</p>
document.getElementById("demo").onclick=function(e)
{
var e=e||event;
alert(e.screenX);
} 瀏覽器核心 要搞清楚瀏覽器核心是什麼,首先應該先搞清楚瀏覽器的構成。簡單來說瀏覽器可以分為 兩部分,shell+核心。其中shell的種類相對比較多,核心則比較少。Shell是指瀏覽器的外殼:例如菜單,工具列等。主要是提供給使用者介面操 作,參數設臵等等。它是調用核心來實現各種功能的。核心才是瀏覽器的核心。核心是基於標記語言顯示內容的程式或模組。也有一些瀏覽器並不區分外殼和核心。 從Mozilla將Gecko獨立出來後,才有了外殼和核心的明確劃分。目前主流的瀏覽器有IE6/7/8、Mozilla、FireFox、Opera、Safari、Chrome、Netscape等。 什麼是瀏覽器核心
瀏覽器核心又可以分成兩部分:渲染引擎(layout engineer或者Rendering Engine)和JS引擎。它負責取得網頁的內容(HTML、XML、映像等等)、整理訊息(例如加入CSS等),以及計算網頁的顯示方式,然後會輸出至 顯示器或印表機。瀏覽器的核心的不同對於網頁的文法解釋會有不同,所以渲染的效果也不相同。JS引擎則是解析Javascript語言,執行javascript語言來實現網頁的動態效果。最開始渲染引 擎和JS引擎並沒有區分的很明確,後來JS引擎越來越獨立,核心就傾向於只指渲染引擎。有一個網頁標準計劃小組製作了一個ACID來測試引擎的相容性和效能。核心的種類很多,如加上沒什麼人使用的非商業的免費核心,可能會有10多種,但是常見的瀏覽器核心可以分這四種:Trident、Gecko、 Presto、Webkit。
渲染引擎 Trident又稱MSHTML,是微軟開發的渲染引擎(包含了Javascript引擎JScript),目前很多瀏覽器都使用這個引擎,例如IE,MaxThon,TT,The World,360,搜狗瀏覽器,Maxthon(最新版已經不使用)等。 Gecko是C++開發的,Open Source的渲染引擎,包括了SpiderMonkey(Rhino)。主要的使用者有Firefox,Netscape6及以上版本,MozillaSuite/SeaMonkey等 。
Webkit是蘋果公司基於KHTML開發的。他包括Webcore和JavaScriptCore(SquirrelFish,V8)兩個引擎。主要的使用者有Safari,Chrome。 Presto由Opera Software公司開始的,用於Opera的渲染引擎。Macromedia Dreamweaver (MX版本及以上)和Adobe Creative Suite 2也使用了Presto的核心。主要的使用者為Opera7及以上。 JS引擎 JavaScript最初由網景公司的Brendan Eich設計,是一種動態、弱類型、基於原型的語言,內臵支援類。以它為基礎,制定了ECMAScript標準。他的起源並不是如《Javascript進階程式設計》書中所述,是Brendan Eich自主發明的。(參考aimingoo的考證文章)JavaScript在瀏覽器的實現中還必須含有DOM和BOM。Web瀏覽器一般使用公用API來建立主機對象來負責將DOM對象反射進JavaScript。
Javascript對滑鼠滾輪事件的處理
W3C並沒有對滑鼠滾輪事件進行規範,各瀏覽器廠商封裝了不同的實現方法,事件屬性也不一樣,號稱最標準的FireFox,用了一個私人實現DOMMouseScroll。不過,其他瀏覽器都是用onmousewheel實現,所以做相容處理的難度也不大。
| 瀏覽器 |
實現方法 |
事件屬性 |
向上滾動 |
向下滾動 |
| FireFox |
DOMMouseScroll |
detail |
-3 |
3 |
| 非FireFox |
onmousewheel |
wheelDelta |
120 |
-120 |
所謂事件屬性,就是滾輪滾動時某個特定變數的變化。該變數不需要使用者定義,是作為事件的屬性出現的。
- 對於FireFox,這個變數是detail:滾輪向上滾動,detail=-3;向下滾動,detail=3。
- 對於非FireFox,這個變數是wheelDelta:滾輪向上滾動,wheelDelta=120;向下滾動,wheelDelta=-120。
另外,還有一點需要注意。
- 在FireFox下,DOMMouseScroll必須通過addEventListener來綁定,如:
element.addEventListener("DOMMouseScroll",fun,false)
- 在非FireFox下,就沒有限制了,除了上述方法,還可用下邊的代碼:
element.onmousewheel=function(){}
筆者最後總結了一段相容代碼,給大家使用。
- 對於實現方法的相容:
/**
* 註冊滾輪事件函數
* @param ele 註冊的事件對象
* @param fun 註冊事件函數
*/
function mouseWheel(ele,fun)
{
(/firefox/i).test(navigator.userAgent)?ele.addEventListener("DOMMouseScroll",fun,false):ele.onmousewheel=fun;
}
- 對於事件屬性的相容:
/**
* 對滾輪事件屬性的相容處理,不管何種瀏覽器,最後統一為:滑鼠輪向上滾動detail=-3,向下滾動detail=3
*/
function fun(e)
{
var e=e||event;
var detail=e.detail||parseInt(-e.wheelDelta/40);
/* 添加代碼 */
}
執行個體:滑鼠在圖片上滾動,圖片放大或縮小。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>效果:滑鼠在圖片上滾動,圖片放大或縮小</title>
</head>
<body>
<img src="/uploads/allimg/121023/1-1210231013513W.jpg" />
<br /><br /><br /><br />
<img src="/uploads/allimg/121023/1-12102321502QO.png" />
<script language="JavaScript" type="text/javascript">
function fun(e)
{
var e=e||event;
var detail=e.detail||parseInt(-e.wheelDelta/40);
this.setAttribute("height",this.offsetHeight+4*detail);
}
function mouseWheel(ele,fun)
{
(/firefox/i).test(navigator.userAgent)?ele.addEventListener("DOMMouseScroll",fun,false):ele.onmousewheel=fun;
}
for(var imgs=document.getElementsByTagName("img"),len=imgs.length,i=0;i<len;i++)
{
mouseWheel(imgs[i],fun)
}
</script>
</body>
</html> Javascript addEventListener和attachEvent的區別
首先,Javascript有3種綁定事件監聽的方法:
- <div onclick="alert("事件綁定成功了!")">事件綁定Demo</div>
- <div id="div1">事件綁定Demo</div>
document.getElementById("div1").onclick=function(){
alert("事件綁定成功了!");
}
- <div id="div1">事件綁定Demo</div>
function fun(){
alert("事件綁定成功了!");
}
document.getElementById("div1").addEventListener("click",fun,false);
addEventListener和attachEvent都是第三種綁定事件監聽的方法,區別如下。
一、addEventListener和attachEvent的相容性問題
- addEventListener是符合W3C規範的事件Binder 方法,FireFox、Chrome、Safari都是用它來綁定事件。
- attachEvent是IE私人的,不符合W3C規範,而且在IE下,只能使用它來綁定事件,addEventListener是無效的。
所以,要想綁定事件,必須處理相容性問題。
二、addEventListener和attachEvent的文法規則
- addEventListener共有3個參數,如下所示:
element.addEventListener(type,listener,useCapture);
| 參數 |
參數說明 |
| element |
要綁定事件的對象,及HTML節點。 |
| type |
事件名稱,注意去掉事件前邊的“on”,比如“onclick”要寫成“click”,“onmouseover”要寫成“mouseover”。 |
| listener |
要綁定的事件監聽函數,注意唯寫函數名,不要帶括弧。 |
| userCapture |
事件監聽方式,只能是true和false:true,採用capture(捕獲)模式;false,採用bubbling(冒泡)模式。如無特殊要求,一般是false。 |
這裡有必要說一下捕獲模式和冒泡模式的區別。
,有兩層div元素,而且都設定有click事件,一般來說,如果我在內層藍色的元素上click不只會觸發藍色元素的click事件,還會同時觸發紅色元素的click事件,而useCapture這個參數就是在控制這時候兩個click事件的先後順序。如果是false,那就會使用bubbling(冒泡)模式,他是從內而外的流程,所以會先執行藍色元素的click事件再執行紅色元素的click事件,如果是true,那就是capture(捕獲)模式,和bubbling(冒泡)模式相反是由外而內,會先執行紅色元素的click事件才執行藍色元素的click事件。
如果不同層的元素使用的useCapture不同,會先從最外層元素往目標元素尋找設定為capture(捕獲)模式的事件,到達目標元素執行目標元素的事件後,再尋原路往外尋找設定為bubbling(冒泡)模式的事件。
- attachEvent共有2個參數,如下所示:
element.attachEvent(type,listener);
| 參數 |
參數說明 |
| element |
要綁定事件的對象,及HTML節點。 |
| type |
事件名稱,注意加上事件前邊的“on”,比如“onclick”和“onmouseover”,這是與addEventListener的區別。 |
| listener |
要綁定的事件監聽函數,注意唯寫函數名,不要帶括弧。 |
三、代碼相容處理
function regEvent(ele, event_name, fun)
{
if (window.attachEvent)
ele.attachEvent(event_name, fun); //IE瀏覽器
else
{
event_name = event_name.replace(/^on/, “”); //如果on開頭,刪除on,如onclick->click
ele.addEventListener(event_name, fun, false); //非IE瀏覽器
}
}
注意,請不要以這種方式來判斷IE瀏覽器:
(/msie/i).test(navigator.userAgent)
此種方法雖然簡單易懂,但是有一個很大的隱患,就是瀏覽器升級以後支援W3C標準了,而並沒有做向後相容,這種情況下就會出現錯誤提示,程式崩潰,增加了維護成本。
Javascript瀏覽器安全色性