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>的內容。 javascript
不推薦使用的嵌入JS腳本的語法
在最先引入<script>元素的時候,該元素與傳統HTML的解析規則是有衝突的。因爲要對這個元素應用特殊的解析規則,所以在那些不支持JavaScript 的瀏覽器一一最典型的是Mosaic-一一中就會致使問題。具體來講,不支持JavaScript的瀏覽幫會把<script>元素的內容直接輸出到頁面中,於是會破壞頁面的佈局和外觀。
html
<script><!--function sayHi(){alert ("Hi! " ) ;--></script>
Netscape與Mosaic協商並提出了一個解決方案,讓不支持<script>元素的瀏覽器可以隱藏嵌入的JavaScript 代碼。這個方案就是把JavaScript 代碼包含在一個HTML 註釋中, 像下面這樣:
給腳本加上HTML註釋後, Mosaic 等瀏覽器就會忽略<script>標籤中的內容,而那些支持JavaScript 的瀏覽器在遇到這種狀況時,則必須進一步確認其中是否包含須要解析的JavaScript 代碼。
雖然這種註釋JavaScript 代碼的格式獲得了全部瀏覽器的承認,也能被正確解釋,但因爲全部的現代瀏覽器都已經支持JavaScript ,所以也就沒有必要再使用這種格式了。 java
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/八、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。 shell
渲染引擎
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);
/* 添加代碼 */
}
實例:鼠標在圖片上滾動,圖片放大或縮小。 ide
<!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都是第三種綁定事件監聽的方法,區別以下。 工具
1、addEventListener和attachEvent的兼容性問題
- addEventListener是符合W3C規範的事件綁定方法,FireFox、Chrome、Safari都是用它來綁定事件。
- attachEvent是IE私有的,不符合W3C規範,並且在IE下,只能使用它來綁定事件,addEventListener是無效的。
因此,要想綁定事件,必須處理兼容性問題。
2、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。 |
這裏有必要說一下捕獲模式和冒泡模式的區別。
![](http://static.javashuo.com/static/loading.gif)
如圖所示,有兩層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 |
要綁定的事件監聽函數,注意只寫函數名,不要帶括號。 |
3、代碼兼容處理
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標準了,而並無作向後兼容,這種狀況下就會出現錯誤提示,程序崩潰,增長了維護成本。