Javascript瀏覽器安全色性

來源:互聯網
上載者:User

標籤:

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種綁定事件監聽的方法:

  1. <div onclick="alert("事件綁定成功了!")">事件綁定Demo</div>
  2. <div id="div1">事件綁定Demo</div>
    document.getElementById("div1").onclick=function(){
        alert("事件綁定成功了!");
    }
  3. <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瀏覽器安全色性

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.