<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # javascript快速入門21--DOM總結 ## 跨瀏覽器開發 市場上的瀏覽器種類多的不計其數,它們的解釋引擎各不相同,期待所有瀏覽器都一致的支持JavaScript,CSS,DOM,那要等到不知什么時候,然而開發者不能干等著那天。歷史上已經有不少方法來解決瀏覽器兼容問題了,主要分為兩種:1.userAgent字符串檢測,2.對象檢測;當然,也不能考慮所有的瀏覽器,我們需要按照客戶需求來,如果可以確信瀏覽網站的用戶都使用或大部分使用IE瀏覽器,那么你大可放心的使用IE專有的那些豐富的擴展,當然,一旦用戶開始轉向另一個瀏覽,那么痛苦的日子便開始了。下面是市場上的主流瀏覽器列表: * Internet Explorer * Mozilla Firefox * Google Chrome * Opera * Safari 注意,瀏覽器總是不斷更新,我們不但要為多種瀏覽器作兼容處理,還要對同一瀏覽器多個版本作兼容處理。比如IE瀏覽器,其6.0版本和7.0版本都很流行,因為微軟IE隨著操作系統綁定安裝(之前也是同步發行,微軟平均每兩年推出一款個人桌面,同樣IE也每兩年更新一次;直到現在,由于火狐的流行,IE工作組才加快IE的更新),所以更新的較慢,6.0版和7.0版有很大差別。 市場上還存在一些其它瀏覽器,但由于它們都是使用的上面所列瀏覽器的核心,或與上面瀏覽器使用了相同的解釋引擎,所以無需多作考慮。下面是主流的瀏覽器解釋引擎列表: 1. Trident Trident (又稱為MSHTML),是微軟的窗口操作系統(Windows)搭載的網頁瀏覽器—Internet Explorer的排版引擎的名稱,它的第一個版本隨著1997年10月Internet Explorer第四版釋出,之后不斷的加入新的技術并隨著新版本的Internet Explorer釋出。在未來最新的Internet Explorer第七版中,微軟將對Trident排版引擎做了的重大的變動,除了加入新的技術之外,并增加對網頁標準的支持。盡管這些變動已經在相當大的程度上落后了其它的排版引擎。使用該引擎的主要瀏覽器:IE,TheWorld,MiniIE,Maxthon,騰訊TT瀏覽器。事實上,這些瀏覽器是直接使用了IE核心,因為其userAgent字符串中返回的信息與IE是一模一樣的! 2. Gecko 壁虎,英文為"Gecko"。Gecko是由Mozilla基金會開發的布局引擎的名字。它原本叫作NGLayout。Gecko的作用是讀取諸如HTML、CSS、XUL和JavaScript等的網頁內容,并呈現到用戶屏幕或打印出來。Gecko已經被許多應用程序所使用,包括若干瀏覽器,例如Firefox、Mozilla Suite、Camino,Seamonkey等等 3. Presto Presto是一個由Opera Software開發的瀏覽器排版引擎,供Opera 7.0及以上使用。Presto取代了舊版Opera 4至6版本使用的Elektra排版引擎,包括加入動態功能,例如網頁或其部分可隨著DOM及Script語法的事件而重新排版。Presto在推出后不斷有更新版本推出,使不少錯誤得以修正,以及閱讀Javascript效能得以最佳化,并成為速度最快的引擎。 4. KHTML 是HTML網頁排版引擎之一,由KDE所開發。KDE系統自KDE2版起,在檔案及網頁瀏覽器使用了KHTML引擎。該引擎以C++編程語言所寫,并以LGPL授權,支援大多數網頁瀏覽標準。由于微軟的Internet Explorer的占有率相當高,不少以FrontPage制作的網頁均包含只有IE才能讀取的非標準語法,為了使KHTML引擎可呈現的網頁達到最多,部分IE專屬的語法也一并支援。目前使用KHTML的瀏覽器有Safari和Google Chrome。而KHTML也產生了許多衍生品,如:WebKit,WebCore引擎 ### 利用userAgent檢測 下面是各大瀏覽器使用彈窗顯示的userAgent字符串 IE瀏覽器:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727) ![](https://box.kancloud.cn/2016-05-17_573b067429c78.png) 火狐瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 ![](https://box.kancloud.cn/2016-05-17_573b06743a2a9.png) Opera瀏覽器:Opera/9.64 (Windows NT 5.1; U; Edition IBIS; zh-cn) Presto/2.1.1 ![](https://box.kancloud.cn/2016-05-17_573b06744b6b1.png) Safari瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16 ![](https://box.kancloud.cn/2016-05-17_573b067461579.png) Google Chrome瀏覽器:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.33 Safari/530.5 ![](https://box.kancloud.cn/2016-05-17_573b06747a3fb.png) 可以使用下面的代碼進行瀏覽器檢測 ``` var Browser = { isIE:navigator.userAgent.indexOf("MSIE")!=-1, isFF:navigator.userAgent.indexOf("Firefox")!=-1, isOpera:navigator.userAgent.indexOf("Opera")!=-1, isSafari:navigator.userAgent.indexOf("Safari")!=-1 }; ``` 但這樣做并不是萬無一失的,一個特例便是Opera可以使用userAgent偽裝自己。下面是偽裝成IE的userAgent:Mozilla/5.0 (Windows NT 5.1; U; Edition IBIS; zh-cn; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.64;在完全偽裝的情況下,最后的“Opera 9.64”這個字符串也不會出現,但Opera也有特殊的識別自身的方法,它會自動聲明一個opera全局變量! 不但如此,我們的檢測還忽略了一點,就是那些使用相同引擎而品牌不同的瀏覽器,所以,直接檢測瀏覽器是沒有必要的,檢測瀏覽器的解釋引擎才是有必要的! ``` var Browser = { isIE:navigator.userAgent.indexOf("MSIE")>-1 && !window.opera, isGecko:navigator.userAgent.indexOf("Gecko")>-1 && !window.opera && navigator.userAgent.indexOf("KHTML") ==-1, isKHTML:navigator.userAgent.indexOf("KHTML")>-1, isOpera:navigator.userAgent.indexOf("Opera")>-1 }; ``` ### 對象檢測 瀏覽器檢測就到此結束了,下面應該講一下對象檢測!對象檢測其實是比瀏覽器檢測更加有效更加科學方法,而且我們之前一直在使用! ``` function addEvent(obj,evtype,bubbles) { if (obj.addEventListener) {....} else if (obj.attachEventListener) {....} } ``` 對象檢測避免了瀏覽器引擎的多樣性,即當我們需要某種功能時,我們直接檢測瀏覽器是否支持該功能,而不用管瀏覽器是什么牌子的! ### 什么時候該使用瀏覽器檢測?什么時候該使用對象檢測? 答案是能使用對象檢測時總該使用對象檢測,只有當必須對瀏覽器進行識別或無法使用對象檢測時才進行userAgent判斷 ``` //一段用于將當前頁面添加到用戶收藏夾的代碼,兩個不同的版本 window.external.addFavorite(location,"收藏頁面");//IE window.sidebar.addPanel("收藏頁面",location,"");//火狐 //由于在火狐下window也具有external屬性,并且在IE下判斷window.external.addFavorite會出錯 if (window.external.addFavorite) {...}//代碼在IE下會出錯 //可以使用瀏覽器檢測,避免意外 if (Browser.isIE) { window.external.addFavorite(location,"收藏頁面");//IE } else if (Browser.isGecko) { window.sidebar.addPanel("收藏頁面",location,"");//火狐及其它相同引擎的瀏覽器 } ``` 當你的腳本和其它腳本一起工作時(尤其和那些有問題的腳本),有時候需要同時使用對象檢測與瀏覽器檢測 ``` //對于window.innerWidth這些屬性,可能有些腳本會創建一個兼容多個瀏覽器的同名屬性 if (isIE) {//它聰明的使用了瀏覽器檢測 window.onresize = function () { window.innerWidth =document.documentElement.clientWidth; window.innerHeight = document.documentElement.clientHeight; }; window.onresize(); } //然而我們的腳本對其進行檢測時就麻煩了 if (window.innerWidth) {//僅當在FF下時(FF支持position:fixed)才這樣做 obj.style.position="fixed"; obj.style.right=window.innerWidth/2+"px"; obj.style.bottom=window.innerWidth/2+"px"; .... } ``` 當然,使用瀏覽器檢測始終是困難重重的,而對于測試文檔是否支持某種特性,使用對象檢測可能是最有效的,還有另一種方法可以直接測試瀏覽器是否支持某標準! ## 測試與DOM標準的一致性 document對象有個implementation屬性,該屬性只有一個方法hasFeature(),用來測試瀏覽器是否支持某個DOM標準! ``` //測試是否支持XML DOM 1.0 var supportXML = document.implementation.hasFeature("XML", "1.0"); ``` | 特 征 | 支持的版本 | 描 述 | | --- | --- | --- | | Core | 1.0, 2.0, 3.0 | 基本的DOM,給予了用層次樹來表示文檔的能力 | | XML | 1.0,2.0,3.0 | 核心的XML擴展,增加了對CDATA Section、處理指令和實體的支持 | | HTML | 1.0,2.0 | XML的HTML擴展,增加了對HTML特定元素和實體的支持 | | Views | 2.0 | 基于特定樣式完成對文檔的格式化 | | StyleSheets | 2.0 | 為文檔關聯樣式表 | | CSS | 2.0 | 支持級聯樣式表1(CSS Level 1) | | CSS2 | 2.0 | 支持級聯樣式表2(CSS Level 2) | | Events | 2.0 | 通用DOM事件 | | UIEvents | 2.0 | 用戶界面事件 | | MouseEvents | 2.0 | 由鼠標引起的事件(點擊、鼠標經過,等等) | | MutationEvents | 2.0 | 當DOM樹發生改變時引發的事件 | | HTMLEvents | 2.0 | HTML 4.01的事件 | | Range | 2.0 | 操作DOM樹中某個特定范圍的對象和方法 | | Traversal | 2.0 | 遍歷DOM樹的方法 | | LS | 3.0 | 在文件和DOM樹之間同步地載入和存儲 | | LS-Async | 3.0 | 在文件和DOM樹之間異步地載入和存儲 | | Validation | 3.0 | 用于修改DOM樹之后仍然保持其有效性的方法 | 盡管這個相當方便,但是,使用implementation.hasFeature()有其明顯的缺陷——決定DOM實現是否對DOM標準的不同的部分相一致的,正是去進行實現的人(或公司)。要讓這個方法對于任何值都返回true,那是很簡單的,但這并不一定表示這個DOM實現真的和所有的標準都一致了。目前為止,最精確的瀏覽器要數Mozilla,但它多少也有一些并不完全和DOM標準一致的地方,這個方法卻返回為true。 ## 錯誤處理 無盡的DOM兼容性問題,如果總是使用對象檢測,就會帶來無盡的if else之類的分支語句,而且檢測某些對象的某些屬性時還會引發錯誤(尤其是在IE下),因為一般的JavaScript對象都可以轉換成布爾值,但瀏覽器內置的一些方法或對象并不是JavaScript創建了,它們不一定能夠轉換成布爾值!所以,使用錯誤處理語句不但避免了分支判斷,而且可以很優雅的處理錯誤! ### try {} catch(e) {} finally {} ``` function addFav(address,name) { try { window.sidebar.addPanel(name,address,"");//FF方法 //在try語句中,如果腳本出錯,會自動跳轉到catch語句執行 } catch(e) {//這里的e是必須的,是語法的一部分,它表示一個錯誤對象 window.external.addFavorite(address,name);//IE //如果在這里還出現錯誤,瀏覽器就會將這個錯誤拋出 } } ``` ### Error對象 JavaScript內置了一個Error構造函數,可以創建一個錯誤對象,并可以使用throw語句手動拋出錯誤! ``` var err = new Error(); throw err; //在IE中,會在錯誤窗口中顯示“未指明的錯誤”,而FF中則是空字符串 //拋出錯誤后,腳本便會停止往下執行 var message = "我拋出的錯誤!";//錯誤描述 err = new Error(message); throw err; ``` 錯誤對象的屬性:message屬性保存與錯誤對象相關的描述文字,number對象保存錯誤代碼。(錯誤號是 32 位的值。高 16 位字是設備代碼,而低字是實際的錯誤代碼,不過錯誤代碼對我們來說是沒什么意義的) ``` try { undefined();//當try語句中腳本出現錯誤時,會自動拋出一個錯誤對象 } catch(e) {//e是自動創建是局部變量,是Error的實例 alert("錯誤信息是:"+e.message+"\n"+"錯誤代碼是:"+e.number); } finally { //finally語句不管出現不出現錯誤,都將執行,一般用于出錯時釋放對象 } ``` ### onerror事件處理 DOM還有個onerror事件處理,當頁面載入出錯,圖象載入出錯及頁面腳本出錯時會執行注冊的事件處理函數,一個常用的方法便是,在事件處理函數中返回true可以阻止瀏覽器出現錯誤提示! ``` window.onerror = function () { alert("出錯時你會看到我的!"); return true; }; ``` 另外一個用法是,可以監測圖像的載入,如果圖像載入出錯,可以重新載入圖像(重新設置src屬性),也可以利用這個方法來測試一下圖像是否存在(比如檢測用戶輸入的遠程圖像的URL是否有效) **盡管使用try {} catch(e) {}語句,及使用onerror事件處理可以處理腳本運行時錯誤,但它們是不能處理語法錯誤的!另外,使用錯誤處理語句并不是為了隱匿錯誤,而只是為了不干擾腳本的繼續執行!** ### 記錄錯誤 處理了這么多錯誤后,記錄錯誤這樣的事情其實已經做過很多次了,主要有下面幾種方法 * 使用alert語句,好處是可以讓腳本暫停運行,壞處便是彈窗不那么好控制 * 使用document.write方法,這種方法自然避免了彈窗沒法關閉的情況,但不好控制腳本運行!另一點便是,使用document.write會清空當前頁面! * 與document.write方法類似的是使用一個自建的控制臺(比如一個DIV),然后將錯誤信息一條一條的添加進去,這種方法肯定比document.write好多了! * 還有另一種方法便是使用瀏覽器內置的控制臺,如在JavaScript里面可以調用Java控制臺并向其中寫入信息(前提是安裝了JRE) ``` java.lang.System.out.println("錯誤信息!");//使用Java控制臺 console.log("錯誤信息!");//使用火狐的控制臺 opera.postError("錯誤信息!");//使用Opera的控制臺 ``` ## 使用庫提高開發效率 庫,就是一些可以方便的應用到當前的開發體系中的代碼資源,JavaScript庫又被稱之為JavaScript框架,它是由一些類和普通函數構成。使用庫,可以使開發者不必關心程序的實現細節而只專心于業務邏輯。有很多流行的庫,它們大都能夠跨瀏覽器工作,并且采用了面向對象的良好編碼方式。 事實上,庫就是將之前我們寫的那些可以跨瀏覽器運行的函數集中到一個JS文件中,以便能在所有頁面都能夠重復利用這些代碼!當然,它們不是簡簡單單的將函數放到一起!下面是一些流行的庫及其優缺點: * Prototype 不要把它和JavaScript里面的prototype相混淆,Prototype是一個JS框架(官方稱之為框架),可以說是最早也是最出名的JS框架了。 它提供了許多JS面向對象的擴展及DOM操作API,之前它一直由于缺乏API文檔而備受詬病,但現在其文檔已很充足。 它的優點顯而易見,它只提供一些核心的,底層的功能,所以代碼精簡,體積較小,易學易用,但由于其只具有底層功能,往往需要協同其它UI庫來運行! 目前,基于Prototype的庫已經有很多,著名的有集成Prototype庫的RoR Ajax庫,以及為Prototype提供許多視覺特效的Scriptaculous庫。 * jQuery jQuery是一款同Prototype一樣優秀js開發庫,特別是對css和XPath的支持,使我們寫js變得更加方便!如果你不是個js高手又想寫出優秀的js效果,jQuery可以幫你達到目的!并且簡潔的語法和高效率一直是jQuery追求的目標。(其官網標語:jQuery將改變您書寫JavaScript的方式!)。 連YAHOO-UI都重用了很多jQuery的函數。支持插件是jQuery的另一大優點,可以無即的擴展其功能。其缺點便是內部結構復雜,代碼較為晦澀,一般的新手根本無法看懂其源碼。所以jQuery適合開發而不適合一個剛開始學習創建JS庫的新手研究其源碼。 * EXT-JS EXT-JS前身是YAHOO-UI,EXT-JS是具有CS風格的Web用戶界面組件 能實現復雜的Layout布局,界面效果可以和BackBase(另一JS庫)媲美,而且使用純javascript代碼開發。真正的可編輯的表格Edit Grid,支持XML和Json數據類型,直接可以遷入grid。許多組件實現了對數據源的支持,例如動態的布局,可編輯的表格控件,動態加載的Tree 控件、動態拖拽效果等等。1.0 beta版開始同Jquery合作,推出基于jQuery的Ext 1.0,提供了更多有趣的功能。 對于一個喜歡JAVA的開發者來說,EXT-JS類似于java的結構,清晰明了,另一特點其可以實現華麗的令人震撼的WEB應用程序。當然,缺點也很嚴重,由于很多HTML及CSS代碼都是EXT-JS自已創建的,所以其界面構造十分復雜,沒有讓我們自己寫CSS的余地。 * Dojo Dojo是目前最為強大的工業級JS框架。它在自己的Wiki上給自己下了一個定義,dojo是一個用JavaScript編寫的開源的DHTML工具箱。dojo很想做一個“大一統”的 工具箱,不僅僅是瀏覽器層面的,野心還是很大的。Dojo包括ajax, browser, event, widget等跨瀏覽器API,包括了JS本身的語言擴展,以及各個方面的工具類庫,和比較完善的UI組件庫,也被廣泛 應用在很多項目中,他的UI組件的特點是通過給html標簽增加tag的方式進行擴展,而不是通過寫JS來生成,dojo的API模仿Java類庫的組織 方式。 用dojo寫Web OS可謂非常方便。dojo現在已經4.0了,dojo強大的地方在于界面和特效的封裝,可以讓開發者快速構建一些兼容標準的界面。 Dojo幾乎集了成了上面的JS庫的優點,其功能非同一般的強大,已得到了IBM和SUN的支持,但是自然的,其體積也十分大,總共有200多KB,另外,其語法也不如jQuery靈活,對JavaScript語言的增強也不如Prototype。 * Scriptaculous Scriptaculous是基于prototype.js框架的JS效果。包含了6個js文件,不同的文件對應不同的js效果,所以說,如果底層用 prototype的話,做js效果用Scriptaculous那是再合適不過的了。優點便是基于Prototype,可以說是Prototype的插件,不同的效果用不同的JS文件分開存放,當然,依賴于Prototype也是其缺點。 * moo.fx moo.fx是一個超級輕量級的javascript特效庫(3k),能夠與prototype.js框架一起使用。它非常快、易于使用、跨瀏覽器、符合標準,提供控制和修改任何HTML元素的CSS屬性,包括顏色。它內置檢查器能夠防止用戶通過多次或瘋狂點擊來破壞效果。moo.fx整體采用模塊化設計,所以可以在它的基礎上開發你需要的任何特效。輕量是其最大的優點,當然其缺點便是輕量級的,但是輕量級的JS庫能有如此強大已經很不錯了。 ### 命名空間 在創建庫之前,第一個要考慮的問題便是如何防止變量重名的問題!解決方案便是使用命名空間!命名空間是JAVA等語言中的一個概念,JavaScript并不支持命名空間,但由于JavaScript的靈活性,我們可以使用對象來模似命名空間! ``` var NameSpace={}; NameSpace.fn1 =function () {}; NameSpace.fn2 =function () {}; ``` 現在,fn1與fn2兩個函數就同屬于NameSpace命名空間中了,它們不會也全局中的fn1或fn2沖突,當然,在使用的時候必需加上NameSpace前綴。這樣使用命名空間并不是最簡單的,因為我們不得不在任何地方調用這些函數的時候都加上NameSpace前綴。下面是使用JavaScript閉包來解決的方案: ``` var NameSpace={}; (function () { function fn1() { } function fn2() { fn1();//在這里調用fn1不需要加NameSpace前綴 } NameSpace.fn1=fn1;//將其添加為全局變量NameSpace的屬性,以便能在函數外訪問 NameSpace.fn2=fn2; })(); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看