javascript高級程序設計(第三版)學習摘錄下

第十章 DOM

  • 100一、每一段標記均可以經過樹中的一個節點來表示:HTML 元素經過元素節點表示,特性(attribute)經過特性節點表示,文檔類型經過文檔類型節點表示,而註釋則經過註釋節點表示。總共有 12 種節點類型,這些類型都繼承自一個基類型
  • 100二、JavaScript 中的全部節點類型都繼承自 Node 類型,所以全部節點類型都共享着相同的基本屬性和方法
  • 100三、全部節點都有的最後一個屬性是 ownerDocument ,該屬性指向表示整個文檔的文檔節點。這種關係表示的是任何節點都屬於它所在的文檔,任何節點都不能同時存在於兩個或更多個文檔中。經過這個屬性,咱們能夠沒必要在節點層次中經過層層回溯到達頂端,而是能夠直接訪問文檔節點
  • 100四、若是須要把節點放在 childNodes 列表中某個特定的位置上,而不是放在末尾,那麼能夠使用insertBefore() 方法。這個方法接受兩個參數:要插入的節點和做爲參照的節點。插入節點後,被插入的節點會變成參照節點的前一個同胞節點( previousSibling ),同時被方法返回。若是參照節點是null ,則 insertBefore() 與 appendChild() 執行相同的操做
  • 100五、 replaceChild() 方法接受的兩個參數是:要插入的節點和要替換的節點。要替換的節點將由這個方法返回並從文檔樹中被移除,同時由要插入的節點佔據其位置
  • 100六、若是隻想移除而非替換節點,能夠使用 removeChild() 方法。這個方法接受一個參數,即要移除的節點。被移除的節點將成爲方法的返回值
  • 100七、要使用這幾個方法必須先取得父節點(使用 parentNode 屬性)。另外,並非全部類型的節點都有子節點,若是在不支持子節點的節點上調用了這些方法,將會致使錯誤發生
  • 100八、 cloneNode() ,用於建立調用這個方法的節點的一個徹底相同的副本。 cloneNode() 方法接受一個布爾值參數,表示是否執行深複製
  • 100九、cloneNode() 方法不會複製添加到 DOM 節點中的 JavaScript 屬性,例如事件處理程序等。這個方法只複製特性、(在明確指定的狀況下也複製)子節點,其餘一切都不會複製。IE 在此存在一個 bug,即它會複製事件處理程序,因此咱們建議在複製以前最好先移除事件處理程序
  • 10十、最後一個方法是 normalize() ,這個方法惟一的做用就是處理文檔樹中的文本節點。因爲解析器的實現或 DOM 操做等緣由,可能會出現文本節點不包含文本,或者接連出現兩個文本節點的狀況。當在某個節點上調用這個方法時,就會在該節點的後代節點中查找上述兩種狀況。若是找到了空文本節點,則刪除它;若是找到相鄰的文本節點,則將它們合併爲一個文本節點
  • 10十一、雖然 DOM 標準規定 Document 節點的子節點能夠是 DocumentType 、 Element 、 ProcessingIn-struction 或 Comment ,但還有兩個內置的訪問其子節點的快捷方式。第一個就是 documentElement屬性,該屬性始終指向 HTML 頁面中的 <html> 元素。另外一個就是經過 childNodes 列表訪問文檔元素,但經過 documentElement 屬性則能更快捷、更直接地訪問該元素
  • 10十二、全部瀏覽器都支持 document.documentElement 和 document.body 屬性
  • 101三、做爲 HTMLDocument 的一個實例, document 對象還有一些標準的 Document 對象所沒有的屬性。這些屬性提供了 document 對象所表現的網頁的一些信息。其中第一個屬性就是 title ,包含着<title> 元素中的文本——顯示在瀏覽器窗口的標題欄或標籤頁上。經過這個屬性能夠取得當前頁面的標題,也能夠修改當前頁面的標題並反映在瀏覽器的標題欄中。修改 title 屬性的值不會改變 <title>元素
  • 101四、 URL 屬性中包含頁面完整的 URL(即地址欄中顯示的 URL), domain 屬性中只包含頁面的域名,而 referrer屬性中則保存着連接到當前頁面的那個頁面的 URL。在沒有來源頁面的狀況下, referrer 屬性中可能會包含空字符串。全部這些信息都存在於請求的 HTTP 頭部,只不過是經過這些屬性讓咱們可以在JavaScrip 中訪問它們而已
  • 101五、當頁面中包含來自其餘子域的框架或內嵌框架時,可以設置 document.domain 就很是方便了。因爲 跨 域 安 全 限 制 , 來 自 不 同 子 域 的 頁 面 無 法 通 過 JavaScript 通 信 。 而 通 過 將 每 個 頁 面 的document.domain 設置爲相同的值,這些頁面就能夠互相訪問對方包含的 JavaScript 對象了
  • 101六、假設有一個頁面加載自 www.wrox.com,其中包含一個內嵌框架,框架內的頁面加載自 p2p.wrox.com。因爲 document.domain 字符串不同,內外兩個頁面之間沒法相互訪問對方的 JavaScript 對象。但若是將這兩個頁面的 document.domain 值都設置爲 "wrox.com" ,它們之間就能夠通訊了。瀏覽器對 domain 屬性還有一個限制,即若是域名一開始是「鬆散的」(loose),那麼不能將它再設置爲「緊繃的」(tight)。換句話說,在將 document.domain 設置爲 "wrox.com" 以後,就不能再將其設置回 "p2p.wrox.com" ,不然將會致使錯誤
  • 101七、HTMLCollection 對象還有一個方法,叫作 namedItem() ,使用這個方法能夠經過元素的 name特性取得集合中的項。對 HTMLCollection 而言,咱們能夠向方括號中傳入數值或字符串形式的索引值。在後臺,對數值索引就會調用 item() ,而對字符串索引就會調用 namedItem()
  • 101八、有一個 document 對象的功能已經存在不少年了,那就是將輸出流寫入到網頁中的能力。這個能力體如今下列 4 個方法中: write() 、 writeln() 、 open() 和 close() 。其中, write() 和 writeln()方法都接受一個字符串參數,即要寫入到輸出流中的文本。 write() 會原樣寫入,而 writeln() 則會在字符串的末尾添加一個換行符( n )。在頁面被加載的過程當中,能夠使用這兩個方法向頁面中動態地加入內容
  • 101九、方法 open() 和 close() 分別用於打開和關閉網頁的輸出流
  • 1020、每一個元素都有一或多個特性,這些特性的用途是給出相應元素或其內容的附加信息。操做特性的DOM 方法主要有三個,分別是 getAttribute() 、 setAttribute() 和 removeAttribute()
  • 102一、與 getAttribute() 對應的方法是 setAttribute() ,這個方法接受兩個參數:要設置的特性名和值。若是特性已經存在, setAttribute() 會以指定的值替換現有的值;若是特性不存在, setAttribute()則建立該屬性並設置相應的值
  • 102二、 removeAttribute() ,這個方法用於完全刪除元素的特性。調用這個方法不只會清除特性的值,並且也會從元素中徹底刪除特性
  • 102三、使用 document.createElement() 方法能夠建立新元素。這個方法只接受一個參數,即要建立元素的標籤名。這個標籤名在 HTML 文檔中不區分大小寫,而在 XML(包括 XHTML)文檔中,則是區分大小寫的
  • 102四、文本節點由 Text 類型表示,包含的是能夠照字面解釋的純文本內容。純文本中能夠包含轉義後的HTML 字符,但不能包含 HTML 代碼
  • 102五、能夠使用 document.createTextNode() 建立新文本節點,這個方法接受一個參數——要插入節點中的文本
  • 102六、使用 document.createComment() 併爲其傳遞註釋文本也能夠建立註釋節點
  • 102七、雖然不能把文檔片斷直接添加到文檔中,但能夠將它做爲一個「倉庫」來使用,便可以在裏面保存未來可能會添加到文檔中的節點。要建立文檔片斷,能夠使用 document.createDocumentFragment() 方法
  • 102八、文檔片斷繼承了 Node 的全部方法,一般用於執行那些針對文檔的 DOM操做。若是將文檔中的節點添加到文檔片斷中,就會從文檔樹中移除該節點,也不會從瀏覽器中再看到該節點。添加到文檔片斷中的新節點一樣也不屬於文檔樹。能夠經過 appendChild() 或insertBefore() 將文檔片斷中內容添加到文檔中。在將文檔片斷做爲參數傳遞給這兩個方法時,實際上只會將文檔片斷的全部子節點添加到相應位置上;文檔片斷自己永遠不會成爲文檔樹的一部分
  • 102九、Attr 對象有 3 個屬性: name 、 value 和 specified 。其中, name 是特性名稱(與 nodeName 的值相同), value 是特性的值(與 nodeValue 的值相同),而 specified 是一個布爾值,用以區別特性是在代碼中指定的,仍是默認的
  • 1030、理解 NodeList 及其「近親」 NamedNodeMap 和 HTMLCollection ,是從總體上透徹理解 DOM 的關鍵所在。這三個集合都是「動態的」;換句話說,每當文檔結構發生變化時,它們都會獲得更新。所以,它們始終都會保存着最新、最準確的信息。從本質上說,全部 NodeList 對象都是在訪問 DOM文檔時實時運行的查詢
  • 103一、通常來講,應該儘可能減小訪問 NodeList 的次數。由於每次訪問 NodeList ,都會運行一次基於文檔的查詢。因此,能夠考慮將從 NodeList 中取得的值緩存起來
  • 103二、querySelector() 方法接收一個 CSS 選擇符,返回與該模式匹配的第一個元素,若是沒有找到匹配的元素,返回 null 。
  • 103三、querySelectorAll() 方法接收的參數與 querySelector() 方法同樣,都是一個 CSS 選擇符,但返回的是全部匹配的元素而不只僅是一個元素。這個方法返回的是一個 NodeList 的實例
  • 103四、若是傳入了瀏覽器不支持的選擇符或者選擇符中有語法錯誤,querySelectorAll() 會拋出錯誤
  • 103五、Selectors API Level 2 規範爲 Element 類型新增了一個方法 matchesSelector() 。這個方法接收一個參數,即 CSS 選擇符,若是調用元素與該選擇符匹配,返回 true ;不然,返回 false
  • 103六、對於元素間的空格,IE9及以前版本不會返回文本節點,而其餘全部瀏覽器都會返回文本節點
  • 103七、支持 getElementsByClassName() 方法的瀏覽器有 IE 9+、Firefox 3+、Safari 3.1+、Chrome 和Opera 9.5+
  • 103八、新增了 document.hasFocus() 方法,這個方法用於肯定文檔是否得到了焦點
  • 103九、使用 document.readyState 的最恰當方式,就是經過它來實現一個指示文檔已經加載完成的指示器。支持 readyState 屬性的瀏覽器有 IE4+、Firefox 3.6+、Safari、Chrome和 Opera 9+
  • 1040、自從 IE6 開始區分渲染頁面的模式是標準的仍是混雜的,檢測頁面的兼容模式就成爲瀏覽器的必要功能。IE 爲此給 document 添加了一個名爲 compatMode 的屬性,這個屬性就是爲了告訴開發人員瀏覽器採用了哪一種渲染模式。就像下面例子中所展現的那樣,在標準模式下, document.compatMode 的值等於 "CSS1Compat" ,而在混雜模式下, document.compatMode 的值等於 "BackCompat"。
  • 104一、HTML5規定能夠爲元素添加非標準的屬性,但要添加前綴 data- ,目的是爲元素提供與渲染無關的信息,或者提供語義信息。這些屬性能夠任意添加、隨便命名,只要以 data- 開頭便可
  • 104二、在讀模式下, innerHTML 屬性返回與調用元素的全部子節點(包括元素、註釋和文本節點)對應的 HTML 標記。在寫模式下, innerHTML 會根據指定的值建立新的 DOM樹,而後用這個 DOM 樹徹底替換調用元素原先的全部子節點
  • 104三、在寫模式下, innerHTML 的值會被解析爲 DOM 子樹,替換調用元素原來的全部子節點。由於它的值被認爲是 HTML,因此其中的全部標籤都會按照瀏覽器處理 HTML 的標準方式轉換爲元素(一樣,這裏的轉換結果也因瀏覽器而異)。若是設置的值僅是文本而沒有 HTML 標籤,那麼結果就是設置純文本
  • 104四、 innerHTML 字符串一開始(並且整個)就是一個「無做用域的元素」,因此這個字符串會變成空字符串
  • 104五、不支持 innerHTML 的元素有: <col> 、 <colgroup> 、<frameset> 、 <head> 、 <html> 、 <style> 、 <table> 、<tbody> 、<thead> 、<tfoot> 和 <tr> 。此外,在 IE8 及更早版本中, <title> 元素也沒有 innerHTML 屬性
  • 104六、在讀模式下, outerHTML 返回調用它的元素及全部子節點的 HTML 標籤。在寫模式下, outerHTML會根據指定的 HTML 字符串建立新的 DOM子樹,而後用這個 DOM 子樹徹底替換調用元素。
  • 104七、因爲 IE9 以前的版本與其餘瀏覽器在處理文本節點中的空白符時有差別,所以就出現了 children屬性。這個屬性是 HTMLCollection 的實例,只包含元素中一樣仍是元素的子節點。除此以外,children 屬性與 childNodes 沒有什麼區別,即在元素只包含元素子節點時,這兩個屬性的值相同
  • 104八、在實際開發中,常常須要知道某個節點是否是另外一個節點的後代。調用 contains() 方法的應該是祖先節點,也就是搜索開始的節點,這個方法接收一個參數,即要檢測的後代節點。若是被檢測的節點是後代節點,該方法返回 true ;不然,返回 false 。
  • 104九、innerText 與 textContent 返回的內容並不徹底同樣。好比,innerText 會忽略行內的樣式和腳本,而 textContent 則會像返回其餘文本同樣返回行內的樣式和腳本代碼。避免跨瀏覽器兼容問題的最佳途徑,就是從不包含行內樣式或行內腳本的 DOM 子樹副本或 DOM 片斷中讀取文本
  • 1050、scrollIntoViewIfNeeded(alignCenter) :只在當前元素在視口中不可見的狀況下,才滾動瀏覽器窗口或容器元素,最終讓它可見。若是當前元素在視口中可見,這個方法什麼也不作。若是將可選的 alignCenter 參數設置爲 true ,則表示儘可能將元素顯示在視口中部(垂直方向)。Safari 和 Chrome 實現了這個方法
  • 105一、在標準模式下,全部度量值都必須指定一個度量單位。在混雜模式下,能夠將style.width 設置爲 "20" ,瀏覽器會假設它是 "20px" ;但在標準模式下,將style.width 設置爲 "20" 會致使被忽略——由於沒有度量單位。在實踐中,最好始終都指定度量單位
  • 105二、經過 cssText 屬性能夠訪問style特性中的CSS代碼。在讀取模式下, cssText 返回瀏覽器對 style特性中 CSS 代碼的內部表示。在寫入模式下,賦給 cssText 的值會重寫整個 style 特性的值;也就是說,之前經過 style 特性指定的樣式信息都將丟失
  • 105三、若是你須要更多信息,能夠使用 getPropertyCSSValue() 方法,它返回一個包含兩個屬性的 CSSValue 對象,這兩個屬性分別是: cssText 和 cssValueType 。其中, cssText 屬性的值與 getPropertyValue() 返回的值相同,而 cssValueType 屬性則是一個數值常量,表示值的類型:0 表示繼承的值,1 表示基本的值,2 表示值列表,3 表示自定義的值
  • 105四、要從元素的樣式中移除某個 CSS 屬性,須要使用 removeProperty() 方法。使用這個方法移除一個屬性,意味着將會爲該屬性應用默認的樣式(從其餘樣式表經層疊而來)。例如,要移除經過 style特性設置的 border 屬性
  • 105五、 getComputedStyle() 方法返回一個 CSSStyleDeclaration 對象(與 style 屬性的類型相同),其中包含當前元素的全部計算的樣式。IE 不支持 getComputedStyle() 方法,但它有一種相似的概念。在 IE 中,每一個具備 style 屬性的元素還有一個 currentStyle 屬性。這個屬性是 CSSStyleDeclaration 的實例,包含當前元素所有計算後的樣式
  • 105六、不管在哪一個瀏覽器中,最重要的一條是要記住全部計算的樣式都是隻讀的;不能修改計算後樣式對象中的 CSS 屬性。此外,計算後的樣式也包含屬於瀏覽器內部樣式表的樣式信息,所以任何具備默認值的 CSS 屬性都會表如今計算後的樣式中。例如,全部瀏覽器中的 visibility 屬性都有一個默認值,但這個值會因實現而異
  • 105七、CSSStyleSheet 類型表示的是樣式表,包括經過 <link> 元素包含的樣式表和在 <style> 元素中定義的樣式表
  • 105八、從樣式表中刪除規則的方法是 deleteRule() ,這個方法接受一個參數:要刪除的規則的位置
  • 105九、首先要介紹的屬性涉及偏移量(offset dimension),包括元素在屏幕上佔用的全部可見的空間。元素的可見大小由其高度、寬度決定,包括全部內邊距、滾動條和邊框大小(注意,不包括外邊距)
  • 1060、全部這些偏移量屬性都是隻讀的,並且每次訪問它們都須要從新計算。所以,應該儘可能避免重複訪問這些屬性;若是須要重複使用其中某些屬性的值,能夠將它們保存在局部變量中,以提升性能。

第十一章 DOM擴展、第十二章 DOM2和DOM3

  • 110一、querySelector() 方法接收一個 CSS 選擇符,返回與該模式匹配的第一個元素,若是沒有找到匹配的元素,返回 null
  • 110二、querySelectorAll() 方法接收的參數與 querySelector() 方法同樣,都是一個 CSS 選擇符,但返回的是全部匹配的元素而不只僅是一個元素。這個方法返回的是一個 NodeList 的實例。返回的值其實是帶有全部屬性和方法的 NodeList ,而其底層實現則相似於一組元素的快照,而非不斷對文檔進行搜索的動態查詢
  • 110三、childElementCount :返回子元素(不包括文本節點和註釋)的個數;firstElementChild :指向第一個子元素; firstChild 的元素版;lastElementChild :指向最後一個子元素; lastChild 的元素版; previousElementSibling :指向前一個同輩元素; previousSibling 的元素版;nextElementSibling :指向後一個同輩元素; nextSibling 的元素版
  • 110四、getElementsByClassName() 方法接收一個參數,即一個包含一或多個類名的字符串,返回帶有指定類的全部元素的 NodeList。傳入多個類名時,類名的前後順序不重要。由於返回的對象是 NodeList ,因此使用這個方法與使用 getElementsByTagName()。以及其餘返回 NodeList 的 DOM 方法都具備一樣的性能問題。支持 getElementsByClassName() 方法的瀏覽器有 IE 9+、Firefox 3+、Safari 3.1+、Chrome 和Opera 9.5+
  • 110五、div.classList.remove("user") => add(value) :將給定的字符串值添加到列表中。若是值已經存在,就不添加了;contains(value) :表示列表中是否存在給定的值,若是存在則返回 true ,不然返回 false;remove(value) :從列表中刪除給定的字符串;toggle(value) :若是列表中已經存在給定的值,刪除它;若是列表中沒有給定的值,添加它。支持 classList 屬性的瀏覽器有 Firefox 3.6+和 Chrome
  • 110六、 document.activeElement 屬性,這個屬性始終會引用 DOM 中當前得到了焦點的元素。默認狀況下,文檔剛剛加載完成時, document.activeElement 中保存的是 document.body 元素的引用。文檔加載期間, document.activeElement 的值爲 null
  • 110七、 document.hasFocus() 方法,這個方法用於肯定文檔是否得到了焦點。
  • 110八、實現了這兩個屬性的瀏覽器的包括 IE 4+、Firefox 3+、Safari 4+、Chrome 和 Opera 8+
  • 110九、使用 document.readyState 的最恰當方式,就是經過它來實現一個指示文檔已經加載完成的指示器
  • 11十、在標準模式下, document.compatMode 的值等於 "CSS1Compat" ,而在混雜模式下, document.compatMode 的值等於 "BackCompat"
  • 11十一、HTML5 新增了 document.head 屬性,引用文檔的 <head> 元素。實現 document.head 屬性的瀏覽器包括 Chrome 和 Safari 5
  • 11十二、HTML5規定能夠爲元素添加非標準的屬性,但要添加前綴 data- ,目的是爲元素提供與渲染無關的信息,或者提供語義信息。這些屬性能夠任意添加、隨便命名,只要以 data- 開頭便可
  • 111三、添加了自定義屬性以後,能夠經過元素的 dataset 屬性來訪問自定義屬性的值。 dataset 屬性的值是 DOMStringMap 的一個實例,也就是一個名值對兒的映射。在這個映射中,每一個 data-name 形式的屬性都會有一個對應的屬性,只不過屬性名沒有 data- 前綴(好比,自定義屬性是 data-myname ,那映射中對應的屬性就是 myname )
  • 111四、在讀模式下, innerHTML 屬性返回與調用元素的全部子節點(包括元素、註釋和文本節點)對應的 HTML 標記。在寫模式下, innerHTML 會根據指定的值建立新的 DOM樹,而後用這個 DOM 樹徹底替換調用元素原先的全部子節點
  • 111五、使用 innerHTML 屬性也有一些限制。好比,在大多數瀏覽器中,經過 innerHTML 插入 <script>元素並不會執行其中的腳本。IE8 及更早版本是惟一能在這種狀況下執行腳本的瀏覽器,但必須知足一些條件。一是必須爲 <script> 元素指定 defer 屬性,二是 <script> 元素必須位於(微軟所謂的)「有做用域的元素」(scoped element)以後。 <script> 元素被認爲是「無做用域的元素」(NoScope element),也就是在頁面中看不到的元素,與 <style> 元素或註釋相似。若是經過 innerHTML 插入的字符串開頭就是一個「無做用域的元素」,那麼 IE 會在解析這個字符串前先刪除該元素。div.innerHTML = "<input type=\"hidden\"><script defer>alert('hi');<\/script>"
  • 111六、並非全部元素都支持 innerHTML 屬性。不支持 innerHTML 的元素有: <col> 、 <colgroup> 、<frameset> 、 <head> 、 <html> 、 <style> 、 <table> 、 <tbody> 、 <thead> 、 <tfoot> 和 <tr> 。此外,在 IE8 及更早版本中, <title> 元素也沒有 innerHTML 屬性
  • 111七、IE8 爲此提供了 window.toStaticHTML() 方法,這個方法接收一個參數,即一個 HTML 字符串;返回一個通過無害處理後的版本——從源 HTML 中刪除全部腳本節點和事件處理程序屬性
  • 111八、若是在<div>元素上調用outerHTML,會返回與上面相同的代碼,包括<div>自己。支持outerHTML屬性的瀏覽器有IE4+、Safari 4+、Chrome和Opera 8+。Firefox 7及以前版本都不支持outerHTML屬性
  • 111九、插入標記的最後一個新增方式是 insertAdjacentHTML() 方法。這個方法最先也是在IE中出現的,它接收兩個參數:插入位置和要插入的 HTML 文本。"beforebegin" ,在當前元素以前插入一個緊鄰的同輩元素;"afterbegin" ,在當前元素之下插入一個新的子元素或在第一個子元素以前再插入新的子元素;"beforeend" ,在當前元素之下插入一個新的子元素或在最後一個子元素以後再插入新的子元素;"afterend" ,在當前元素以後插入一個緊鄰的同輩元素。第二個參數是一個 HTML 字符串(與 innerHTML 和 outerHTML的值相同)。支持insertAdjacentHTML() 方法的瀏覽器有 IE、Firefox 8+、Safari、Opera 和 Chrome
  • 1120、scrollIntoView() 能夠在全部 HTML 元素上調用,經過滾動瀏覽器窗口或某個容器元素,調用元素就能夠出如今視口中。若是給這個方法傳入 true 做爲參數,或者不傳入任何參數,那麼窗口滾動以後會讓調用元素的頂部與視口頂部儘量平齊。若是傳入 false 做爲參數,調用元素會盡量所有出如今視口中,(可能的話,調用元素的底部會與視口頂部平齊)。支持 scrollIntoView() 方法的瀏覽器有 IE、Firefox、Safari 和 Opera
  • 112一、children這個屬性是 HTMLCollection 的實例,只包含元素中一樣仍是元素的子節點。除此以外,children 屬性與 childNodes 沒有什麼區別,即在元素只包含元素子節點時,這兩個屬性的值相同。支持 children 屬性的瀏覽器有 IE五、Firefox 3.五、Safari 2(但有 bug)、Safari 3(徹底支持)、Opera8和 Chrome(全部版本)。IE8 及更早版本的 children 屬性中也會包含註釋節點,但 IE9 以後的版本則只返回元素節點
  • 112二、調用 contains() 方法的應該是祖先節點,也就是搜索開始的節點,這個方法接收一個參數,即要檢測的後代節點。若是被檢測的節點是後代節點,該方法返回 true ;不然,返回 false。支持 contains() 方法的瀏覽器有 IE、Firefox 9+、Safari、Opera 和 Chrome
  • 112三、多數狀況下,均可以經過簡單地轉換屬性名的格式來實現轉換。其中一個不能直接轉換的 CSS 屬性就是 float 。因爲 float 是 JavaScript 中的保留字,所以不能用做屬性名。「DOM2 級樣式」規範規定樣式對象上相應的屬性名應該是 cssFloat ;Firefox、Safari、Opera 和 Chrome 都支持這個屬性,而 IE支持的則是 styleFloat
  • 112四、經過 cssText 屬性能夠訪問style特性中的CSS代碼。在讀取模式下, cssText 返回瀏覽器對 style特性中 CSS 代碼的內部表示。在寫入模式下,賦給 cssText 的值會重寫整個 style 特性的值;也就是說,之前經過 style 特性指定的樣式信息都將丟失
  • 112五、getPropertyValue() 方法取得的始終都是 CSS 屬性值的字符串表示。若是你須要更多信息,能夠使用 getPropertyCSSValue() 方法,它返回一個包含兩個屬性的 CSSValue 對象,這兩個屬性分別是: cssText 和 cssValueType 。其中, cssText 屬性的值與getPropertyValue() 返回的值相同,而 cssValueType 屬性則是一個數值常量,表示值的類型:0 表示繼承的值,1 表示基本的值,2 表示值列表,3 表示自定義的值。在實際開發中, getPropertyCSSValue() 使用得比 getPropertyValue() 少得多。IE9+、Safarie3+以及 Chrome 支持這個方法。Firefox 7 及以前版本也提供這個訪問,但調用總返回 null
  • 112六、要從元素的樣式中移除某個 CSS 屬性,須要使用 removeProperty() 方法。使用這個方法移除一個屬性,意味着將會爲該屬性應用默認的樣式(從其餘樣式表經層疊而來)
  • 112七、getComputedStyle() 方法。這個方法接受兩個參數:要取得計算樣式的元素和一個僞元素字符串(例如 ":after" )。若是不須要僞元素信息,第二個參數能夠是 null 。 getComputedStyle() 方法返回一個 CSSStyleDeclaration 對象(與 style 屬性的類型相同),其中包含當前元素的全部計算的樣式。IE 不支持 getComputedStyle() 方法,但它有一種相似的概念。在 IE 中,每一個具備 style 屬性的元素還有一個 currentStyle 屬性。這個屬性是 CSSStyleDeclaration 的實例,包含當前元素所有計算後的樣式。與 DOM 版本的方式同樣,IE 也沒有返回 border 樣式,由於這是一個綜合屬性。不管在哪一個瀏覽器中,最重要的一條是要記住全部計算的樣式都是隻讀的;不能修改計算後樣式對象中的 CSS 屬性。此外,計算後的樣式也包含屬於瀏覽器內部樣式表的樣式信息,所以任何具備默認值的 CSS 屬性都會表如今計算後的樣式中
  • 112八、CSSStyleSheet 類型表示的是樣式表,包括經過 <link> 元素包含的樣式表和在 <style> 元素中定義的樣式表。有讀者可能記得,這兩個元素自己分別是由 HTMLLinkElement 和 HTMLStyleElement 類型表示的。可是, CSSStyleSheet 類型相對更加通用一些,它只表示樣式表,而無論這些樣式表在 HTML中是如何定義的。此外,上述兩個針對元素的類型容許修改 HTML特性,但 CSSStyleSheet 對象則是一套只讀的接口(有一個屬性例外)。disabled :表示樣式表是否被禁用的布爾值。這個屬性是可讀/寫的,將這個值設置爲 true 能夠禁用樣式表
  • 112九、其中三個最經常使用的屬性是 cssText 、 selectorText 和 style 。 cssText 屬性與 style.cssText屬性相似,但並不相同。前者包含選擇符文本和圍繞樣式信息的花括號,後者只包含樣式信息(相似於元素的 style.cssText )。此外, cssText 是隻讀的,而 style.cssText 也能夠被重寫
  • 1130、 insertRule() 方法接受兩個參數:規則文本和表示在哪裏插入規則的索引。Firefox、Safari、Opera 和 Chrome都支持 insertRule() 方法。IE8 及更早版本支持一個相似的方法,名叫 addRule() ,也接收兩必選參數:選擇符文本和 CSS樣式信息;一個可選參數:插入規則的位置
  • 113一、從樣式表中刪除規則的方法是 deleteRule() ,這個方法接受一個參數:要刪除的規則的位置;IE 支持的相似方法叫 removeRule() ,使用方法相同。與添加規則類似,刪除規則也不是實際 Web 開發中常見的作法。考慮到刪除規則可能會影響 CSS層疊的效果,所以請你們慎重使用
  • 113二、偏移量。offsetHeight :元素在垂直方向上佔用的空間大小,以像素計。包括元素的高度、(可見的)水平滾動條的高度、上邊框高度和下邊框高度;offsetWidth :元素在水平方向上佔用的空間大小,以像素計。包括元素的寬度、(可見的)垂直滾動條的寬度、左邊框寬度和右邊框寬度;offsetLeft :元素的左外邊框至包含元素的左內邊框之間的像素距離;offsetTop :元素的上外邊框至包含元素的上內邊框之間的像素距離。要想知道某個元素在頁面上的偏移量,將這個元素的 offsetLeft 和 offsetTop 與其 offsetParent的相同屬性相加,如此循環直至根元素,就能夠獲得一個基本準確的值
  • 113三、全部這些偏移量屬性都是隻讀的,並且每次訪問它們都須要從新計算。所以,應該儘可能避免重複訪問這些屬性;若是須要重複使用其中某些屬性的值,能夠將它們保存在局部變量中,以提升性能
  • 113四、元素的客戶區大小(client dimension),指的是元素內容及其內邊距所佔據的空間大小。有關客戶區大小的屬性有兩個: clientWidth 和 clientHeight 。其中, clientWidth 屬性是元素內容區寬度加上左右內邊距寬度; clientHeight 屬性是元素內容區高度加上上下內邊距高度。注意這兩個屬性不包含邊框(border)
  • 113五、與偏移量類似,客戶區大小也是隻讀的,也是每次訪問都要從新計算的
  • 113六、有些元素(例如<html> 元素),即便沒有執行任何代碼也能自動地添加滾動條;但另一些元素,則須要經過 CSS 的overflow 屬性進行設置才能滾動。scrollHeight :在沒有滾動條的狀況下,元素內容的總高度;scrollWidth :在沒有滾動條的狀況下,元素內容的總寬度;scrollLeft :被隱藏在內容區域左側的像素數。經過設置這個屬性能夠改變元素的滾動位置;scrollTop :被隱藏在內容區域上方的像素數。經過設置這個屬性能夠改變元素的滾動位置
  • 113七、對於 不 包含 滾動 條 的頁 面而 言 , scrollWidth 和 scrollHeight 與 clientWidth 和clientHeight 之間的關係並不十分清晰
  • 113八、在肯定文檔的總高度時(包括基於視口的最小高度時),必須取得 scrollWidth/clientWidth 和scrollHeight/clientHeight 中的最大值,才能保證在跨瀏覽器的環境下獲得精確的結果
  • 113九、經過 scrollLeft 和 scrollTop 屬性既能夠肯定元素當前滾動的狀態,也能夠設置元素的滾動位置。在元素還沒有被滾動時,這兩個屬性的值都等於 0。若是元素被垂直滾動了,那麼 scrollTop 的值會大於 0,且表示元素上方不可見內容的像素高度。若是元素被水平滾動了,那麼 scrollLeft 的值會大於 0,且表示元素左側不可見內容的像素寬度。這兩個屬性都是能夠設置的,所以將元素的scrollLeft 和 scrollTop 設置爲 0,就能夠重置元素的滾動位置
  • 1140、IE、Firefox 3+、Safari 4+、Opera 9.5及 Chrome爲每一個元素都提供了一個 getBoundingClientRect() 方法。這個方法返回會一個矩形對象,包含 4 個屬性: left 、 top 、 right 和 bottom 。這些屬性給出了元素在頁面中相對於視口的位置。可是,瀏覽器的實現稍有不一樣。IE8 及更早版本認爲文檔的左上角座標是(2, 2),而其餘瀏覽器包括 IE9 則將傳統的(0,0)做爲起點座標。所以,就須要在一開始檢查一下位於(0,0)處的元素的位置,在 IE8 及更早版本中,會返回(2,2),而在其餘瀏覽器中會返回(0,0)
  • 114一、對於不支持 getBoundingClientRect() 的瀏覽器,能夠經過其餘手段取得相同的信息。通常來講, right 和 left 的差值與 offsetWidth 的值相等,而 bottom 和 top 的差值與 offsetHeight相等。並且, left 和 top 屬性大體等於使用本章前面定義的 getElementLeft() 和 getElementTop()函數取得的值
  • 114二、DOM2 級在 Document 類型中定義了 createRange() 方法。在兼容 DOM 的瀏覽器中,這個方法屬於 document 對象。使用 hasFeature() 或者直接檢測該方法,均可以肯定瀏覽器是否支持範圍
  • 114三、要使用範圍來選擇文檔中的一部分,最簡的方式就是使用 selectNode() 或 selectNodeContents() 。這兩個方法都接受一個參數,即一個 DOM 節點,而後使用該節點中的信息來填充範圍。其中,selectNode() 方法選擇整個節點,包括其子節點;而 selectNodeContents() 方法則只選擇節點的子節點
  • 114四、要建立複雜的範圍就得使用 setStart() 和 setEnd() 方法。這兩個方法都接受兩個參數:一個參照節點和一個偏移量值。對 setStart() 來講,參照節點會變成 startContainer ,而偏移量值會變成startOffset 。對於 setEnd() 來講,參照節點會變成 endContainer ,而偏移量值會變成 endOffset
  • 114五、使用 insertNode()方法能夠向範圍選區的開始處插入一個節點。<span> 正好被插入到了 "Hello" 中的 "llo" 前面,而該位置就是範圍選區的開始位置。還要注意的是,因爲這裏沒有使用上一節介紹的方法,結果原始的 HTML 並無添加或刪除 <b> 元素。使用這種技術能夠插入一些幫助提示信息,例如在打開新窗口的連接旁邊插入一幅圖像
  • 114六、除了向範圍內部插入內容以外,還能夠環繞範圍插入內容,此時就要使用 surroundContents()方法。這個方法接受一個參數,即環繞範圍內容的節點。在環繞範圍插入內容時,後臺會執行下列步驟:提取出範圍中的內容(相似執行 extractContent() );將給定節點插入到文檔中原來範圍所在的位置上;將文檔片斷的內容添加到給定節點中
  • 114七、所謂摺疊範圍,就是指範圍中未選擇文檔的任何部分。使用 collapse() 方法來摺疊範圍,這個方法接受一個參數,一個布爾值,表示要摺疊到範圍的哪一端。參數 true 表示摺疊到範圍的起點,參數 false 表示摺疊到範圍的終點。要肯定範圍已經摺疊完畢,能夠檢查 collapsed 屬性
  • 114八、能夠使用 cloneRange() 方法複製範圍。這個方法會建立調用它的範圍的一個副本。新建立的範圍與原來的範圍包含相同的屬性,而修改它的端點不會影響原來的範圍
  • 114九、在使用完範圍以後,最好是調用 detach() 方法,以便從建立範圍的文檔中分離出該範圍。調用detach() 以後,就能夠放心地解除對範圍的引用,從而讓垃圾回收機制回收其內存了
  • 1150、IE九、Firefox、Opera、Safari 和 Chrome 全都已經實現了「DOM2 級事件」模塊的核心部分。IE8 是最後一個仍然使用其專有事件系統的主要瀏覽器

第十三章 事件

  • 130一、事件流描述的是從頁面中接收事件的順序。但有意思的是,IE 和 Netscape 開發團隊竟然提出了差很少是徹底相反的事件流的概念。IE 的事件流是事件冒泡流,而 Netscape Communicator 的事件流是事件捕獲流
  • 130二、IE 的事件流叫作事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上傳播到較爲不具體的節點(文檔)
  • 130三、Netscape Communicator團隊提出的另外一種事件流叫作事件捕獲(event capturing)。事件捕獲的思想是不太具體的節點應該更早接收到事件,而最具體的節點應該最後接收到事件。事件捕獲的用意在於在事件到達預約目標以前捕獲它
  • 130四、雖然事件捕獲是 Netscape Communicator 惟一支持的事件流模型,但 IE九、Safari、Chrome、Opera和 Firefox 目前也都支持這種事件流模型。儘管「DOM2 級事件」規範要求事件應該從 document 對象開始傳播,但這些瀏覽器都是從 window 對象開始捕獲事件的。
  • 130五、因爲老版本的瀏覽器不支持,所以不多有人使用事件捕獲。咱們也建議讀者放心地使用事件冒泡,在有特殊須要時再使用事件捕獲
  • 130六、「DOM2級事件」規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。首先發生的是事件捕獲,爲截獲事件提供了機會。而後是實際的目標接收到事件。最後一個階段是冒泡階段,能夠在這個階段對事件作出響應
  • 130七、在 DOM 事件流中,實際的目標( <div> 元素)在捕獲階段不會接收到事件
  • 130八、多數支持 DOM事件流的瀏覽器都實現了一種特定的行爲;即便「DOM2 級事件」規範明確要求捕獲階段不會涉及事件目標,但 IE九、Safari、Chrome、Firefox 和 Opera 9.5 及更高版本都會在捕獲階段觸發事件對象上的事件。結果,就是有兩個機會在目標對象上面操做事件。IE九、Opera、Firefox、Chrome 和 Safari 都支持 DOM 事件流;IE8 及更早版本不支持 DOM 事件流。
  • 130九、將事件處理程序設置爲 null 以後,再單擊按鈕將不會有任何動做發生
  • 13十、「DOM2級事件」定義了兩個方法,用於處理指定和刪除事件處理程序的操做: addEventListener()和 removeEventListener() 。全部 DOM 節點中都包含這兩個方法,而且它們都接受 3 個參數:要處理的事件名、做爲事件處理程序的函數和一個布爾值。最後這個布爾值參數若是是 true ,表示在捕獲階段調用事件處理程序;若是是 false ,表示在冒泡階段調用事件處理程序
  • 13十一、經過 addEventListener() 添加的事件處理程序只能使用 removeEventListener() 來移除;移除時傳入的參數與添加處理程序時使用的參數相同。這也意味着經過 addEventListener() 添加的匿名函數將沒法移除。把傳入的匿名函數賦給一個變量,在添加事件監聽或移除事件監聽使用該變量能夠移除
  • 13十二、大多數狀況下,都是將事件處理程序添加到事件流的冒泡階段,這樣能夠最大限度地兼容各類瀏覽器。最好只在須要在事件到達目標以前截獲它的時候將事件處理程序添加到捕獲階段。若是不是特別須要,咱們不建議在事件捕獲階段註冊事件處理程序
  • 131三、IE 實現了與 DOM 中相似的兩個方法: attachEvent() 和 detachEvent() 。這兩個方法接受相同的兩個參數:事件處理程序名稱與事件處理程序函數。因爲 IE8 及更早版本只支持事件冒泡,因此經過attachEvent() 添加的事件處理程序都會被添加到冒泡階段。注意, attachEvent() 的第一個參數是 "onclick" ,而非 DOM 的 addEventListener() 方法中的 "click"
  • 131四、在 IE 中使用 attachEvent() 與使用 DOM0 級方法的主要區別在於事件處理程序的做用域。在使用 DOM0 級方法的狀況下,事件處理程序會在其所屬元素的做用域內運行;在使用 attachEvent() 方法的狀況下,事件處理程序會在全局做用域中運行,所以 this 等於 window
  • 131五、這裏調用了兩次 attachEvent() ,爲同一個按鈕添加了兩個不一樣的事件處理程序。不過,與 DOM方法不一樣的是,這些事件處理程序不是以添加它們的順序執行,而是以相反的順序被觸發
  • 131六、使用 attachEvent() 添加的事件能夠經過 detachEvent() 來移除,條件是必須提供相同的參數。與 DOM 方法同樣,這也意味着添加的匿名函數將不能被移除。不過,只要可以將對相同函數的引用傳給 detachEvent() ,就能夠移除相應的事件處理程序
  • 131七、在觸發 DOM 上的某個事件時,會產生一個事件對象 event ,這個對象中包含着全部與事件有關的信息。包括致使事件的元素、事件的類型以及其餘與特定事件相關的信息。例如,鼠標操做致使的事件對象中,會包含鼠標位置的信息,而鍵盤操做致使的事件對象中,會包含與按下的鍵有關的信息。全部瀏覽器都支持 event 對象,但支持方式不一樣
  • 131八、在事件處理程序內部,對象 this 始終等於 currentTarget 的值,而 target 則只包含事件的實際目標。若是直接將事件處理程序指定給了目標元素,則 this 、 currentTarget 和 target 包含相同的值。若是事件處理程序存在於按鈕的父節點中(例如 document.body ),那麼這些值是不相同的
  • 131九、事件委託是經過事件冒泡來實現的
  • 1320、要阻止特定事件的默認行爲,能夠使用 preventDefault() 方法。例如,連接的默認行爲就是在被單擊時會導航到其 href 特性指定的 URL。若是你想阻止連接導航這一默認行爲,那麼經過連接的onclick 事件處理程序能夠取消它
  • 132一、只有 cancelable 屬性設置爲 true 的事件,才能夠使用 preventDefault() 來取消其默認行爲
  • 132二、 stopPropagation() 方法用於當即中止事件在 DOM 層次中的傳播,即取消進一步的事件捕獲或冒泡
  • 132三、事件對象的eventPhase屬性,能夠用來肯定事件當前正位於事件流的哪一個階段。若是是在捕獲階段調用的事件處理程序,那麼 eventPhase 等於 1 ;若是事件處理程序處於目標對象上,則event-Phase等於2;若是是在冒泡階段調用的事件處理程序, eventPhase 等於 3
  • 132四、只有在事件處理程序執行期間, event 對象纔會存在;一旦事件處理程序執行完成, event 對象就會被銷燬
  • 132五、 returnValue 屬性至關於 DOM中的 preventDefault() 方法,它們的做用都是取消給定事件的默認行爲。只要將 returnValue 設置爲 false ,就能夠阻止默認行爲
  • 132六、cancelBubble 屬性與 DOM 中的 stopPropagation() 方法做用相同,都是用來中止事件冒泡的。因爲 IE 不支持事件捕獲,於是只能取消事件冒泡;但 stopPropagatioin() 能夠同時取消事件捕獲和冒泡
  • 132七、在 onclick 事件處理程序中將 cancelBubble 設置爲 true ,就可阻止事件經過冒泡而觸發document.body 中註冊的事件處理程序
  • 132八、JavaScript 中最經常使用的一個事件就是 load 。當頁面徹底加載後(包括全部圖像、JavaScript 文件、CSS 文件等外部資源),就會觸發 window 上面的 load 事件
  • 132九、與 load 事件對應的是 unload 事件,這個事件在文檔被徹底卸載後觸發。只要用戶從一個頁面切換到另外一個頁面,就會發生 unload 事件
  • 1330、當瀏覽器窗口被調整到一個新的高度或寬度時,就會觸發 resize 事件。這個事件在 window (窗口)上面觸發,所以能夠經過 JavaScript 或者 <body> 元素中的 onresize 特性來指定事件處理程序
  • 133一、關於什麼時候會觸發 resize 事件,不一樣瀏覽器有不一樣的機制。IE、Safari、Chrome 和 Opera 會在瀏覽器窗口變化了 1 像素時就觸發 resize 事件,而後隨着變化不斷重複觸發。Firefox 則只會在用戶中止調整窗口大小時纔會觸發 resize 事件。因爲存在這個差異,應該注意不要在這個事件的處理程序中加入大計算量的代碼,由於這些代碼有可能被頻繁執行,從而致使瀏覽器反應明顯變慢。瀏覽器窗口最小化或最大化時也會觸發 resize 事件
  • 133二、焦點事件會在頁面元素得到或失去焦點時觸發。利用這些事件並與document.hasFocus()方法及document.activeElement 屬性配合,能夠知曉用戶在頁面上的行蹤
  • 133三、 focus 和 blur ,它們都是 JavaScript 早期就獲得全部瀏覽器支持的事件。這些事件的最大問題是它們不冒泡。所以,IE 的 focusin 和 focusout 與 Opera 的 DOMFocusIn和 DOMFocusOut 纔會發生重疊。IE 的方式最後被 DOM3 級事件採納爲標準方式
  • 133四、鼠標事件中還有一類滾輪事件。而說是一類事件,其實就是一個 mousewheel 事件。這個事件跟蹤鼠標滾輪,相似於 Mac 的觸控板
  • 133五、鼠標事件都是在瀏覽器視口中的特定位置上發生的。這個位置信息保存在事件對象的 clientX 和clientY 屬性中。全部瀏覽器都支持這兩個屬性,它們的值表示事件發生時鼠標指針在視口中的水平和垂直座標。注意,這些值中不包括頁面滾動的距離,所以這個位置並不表示鼠標在頁面上的位置。
  • 133六、頁面座標經過事件對象的pageX和pageY屬性,能告訴你事件是在頁面中的什麼位置發生的。換句話說,這兩個屬性表示鼠標光標在頁面中的位置,所以座標是從頁面自己而非視口的左邊和頂邊計算的
  • 133七、IE8 及更早版本不支持事件對象上的頁面座標,不過使用客戶區座標和滾動信息能夠計算出來。這時候須要用到 document.body (混雜模式)或 document.documentElement (標準模式)中的scrollLeft 和 scrollTop 屬性
  • 133八、經過 screenX 和 screenY 屬性就能夠肯定鼠標事件發生時鼠標指針相對於整個屏幕的座標信息
  • 133九、雖然鼠標事件主要是使用鼠標來觸發的,但在按下鼠標時鍵盤上的某些鍵的狀態也能夠影響到所要採起的操做。這些修改鍵就是 Shift、Ctrl、Alt 和 Meta(在 Windows鍵盤中是 Windows鍵,在蘋果機中是 Cmd 鍵),它們常常被用來修改鼠標事件的行爲。DOM 爲此規定了 4 個屬性,表示這些修改鍵的狀態: shiftKey 、 ctrlKey 、 altKey 和 metaKey 。這些屬性中包含的都是布爾值,若是相應的鍵被按下了,則值爲 true ,不然值爲 false 。當某個鼠標事件發生時,經過檢測這幾個屬性就能夠肯定用戶是否同時按下了其中的鍵
  • 1340、DOM經過 event 對象的 relatedTarget 屬性提供了相關元素的信息。這個屬性只對於 mouseover和 mouseout 事件才包含值;對於其餘事件,這個屬性的值是 null
  • 134一、只有在主鼠標按鈕被單擊(或鍵盤迴車鍵被按下)時纔會觸發 click事件,所以檢測按鈕的信息並非必要的。但對於 mousedown 和 mouseup 事件來講,則在其 event 對象存在一個 button 屬性,表示按下或釋放的按鈕。DOM 的 button 屬性可能有以下 3 個值: 0 表示主鼠標按鈕, 1 表示中間的鼠標按鈕(鼠標滾輪按鈕), 2 表示次鼠標按鈕
  • 134二、「DOM2 級事件」規範在 event 對象中還提供了 detail 屬性,用於給出有關事件的更多信息。對於鼠標事件來講, detail 中包含了一個數值,表示在給定位置上發生了多少次單擊。在同一個元素上相繼地發生一次 mousedown 和一次 mouseup 事件算做一次單擊。 detail 屬性從 1 開始計數,每次單擊發生後都會遞增
  • 134三、IE 6.0 首先實現了 mousewheel 事件。此後,Opera、Chrome 和 Safari 也都實現了這個事件。當用戶經過鼠標滾輪與頁面交互、在垂直方向上滾動頁面時(不管向上仍是向下),就會觸發 mousewheel事件。這個事件能夠在任何元素上面觸發,最終會冒泡到 document (IE8)或 window (IE九、Opera、Chrome 及 Safari)對象。與 mousewheel 事件對應的 event 對象除包含鼠標事件的全部標準信息外,還包含一個特殊的 wheelDelta 屬性。當用戶向前滾動鼠標滾輪時, wheelDelta 是 120 的倍數;當用戶向後滾動鼠標滾輪時, wheelDelta 是120 的倍數。
  • 134四、多數狀況下,只要知道鼠標滾輪滾動的方向就夠了,而這經過檢測 wheelDelta 的正負號就能夠肯定。有一點要注意:在 Opera 9.5 以前的版本中, wheelDelta 值的正負號是顛倒的。若是你打算支持早期的 Opera 版本,就須要使用瀏覽器檢測技術來肯定實際的值
  • 134五、鍵盤事件keydown、keypress、keyup與鼠標事件同樣,都支持相同的修改鍵。並且,鍵盤事件的事件對象中也有 shiftKey 、 ctrlKey 、 altKey 和 metaKey 屬性。IE 不支持 metaKey
  • 134六、鍵碼在發生 keydown 和 keyup 事件時, event 對象的 keyCode 屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字符鍵, keyCode 屬性的值與 ASCII 碼中對應小寫字母或數字的編碼相同
  • 134七、發生 keypress 事件意味着按下的鍵會影響到屏幕中文本的顯示。在全部瀏覽器中,按下可以插入或刪除字符的鍵都會觸發 keypress 事件;按下其餘鍵可否觸發此事件因瀏覽器而異
  • 134八、IE8及以前版本和Opera則是在 keyCode 中保存字符的ASCII編碼。要想以跨瀏覽器的方式取得字符編碼,必須首先檢測 charCode 屬性是否可用,若是不可用則使用 keyCode。在取得了字符編碼以後,就能夠使用 String.fromCharCode() 將其轉換成實際的字符
  • 134九、儘管全部瀏覽器都實現了某種形式的鍵盤事件,DOM3 級事件仍是作出了一些改變。好比,DOM3級事件中的鍵盤事件,再也不包含 charCode 屬性,而是包含兩個新屬性: key 和 char。其中, key 屬性是爲了取代 keyCode 而新增的,它的值是一個字符串。在按下某個字符鍵時, key的值就是相應的文本字符(如「k」或「M」);在按下非字符鍵時, key 的值是相應鍵的名(如「Shift」或「Down」)。而 char 屬性在按下字符鍵時的行爲與 key 相同,但在按下非字符鍵時值爲 null。因爲存在跨瀏覽器問題,所以本書不推薦使用 key 、 keyIdentifier 或 char
  • 1350、 event 對象上還有一個屬性,叫 inputMethod ,表示把文本輸入到文本框中的方式。 1,表示是使用鍵盤輸入的;2,表示文本是粘貼進來的; 3,表示文本是拖放進來的; 7,表示文本是經過語音輸入的
  • 135一、支持 textInput 屬性的瀏覽器有 IE9+、Safari 和 Chrome。只有 IE 支持 inputMethod 屬性
  • 135二、在全部瀏覽器中均可以取消這個事件:在兼容 DOM 的瀏覽器中,使用 event.preventDefalut() ;在 IE 中,將 event.returnValue 的值設置爲 false 。由於 contextmenu 事件屬於鼠標事件,因此其事件對象中包含與光標位置有關的全部屬性。一般使用 contextmenu 事件來顯示自定義的上下文菜單,而使用 onclick 事件處理程序來隱藏該菜單。支持 contextmenu 事件的瀏覽器有 IE、Firefox、Safari、Chrome 和 Opera 11+
  • 135三、之因此有發生在 window 對象上的 beforeunload 事件,是爲了讓開發人員有可能在頁面卸載前阻止這一操做。這個事件會在瀏覽器卸載頁面以前觸發,能夠經過它來取消卸載並繼續使用原有頁面。可是,不能完全取消這個事件,由於那就至關於讓用戶沒法離開當前頁面了。爲此,這個事件的意圖是將控制權交給用戶。顯示的消息會告知用戶頁面行將被卸載(正由於如此纔會顯示這個消息),詢問用戶是否真的要關閉頁面,仍是但願繼續留下來。IE 和 Firefox、Safari 和 Chrome 都支持 beforeunload 事件,也都會彈出這個對話框詢問用戶是否真想離開。Opera 11 及以前的版本不支持 beforeunload 事件
  • 135四、touchstart :當手指觸摸屏幕時觸發;即便已經有一個手指放在了屏幕上也會觸發。touchmove :當手指在屏幕上滑動時連續地觸發。在這個事件發生期間,調用 preventDefault()能夠阻止滾動。touchend :當手指從屏幕上移開時觸發。touchcancel :當系統中止跟蹤觸摸時觸發。關於此事件的確切觸發時間,文檔中沒有明確說明。上面這幾個事件都會冒泡,也均可以取消
  • 135五、gesturestart :當一個手指已經按在屏幕上而另外一個手指又觸摸屏幕時觸發。gesturechange :當觸摸屏幕的任何一個手指的位置發生變化時觸發。gestureend :當任何一個手指從屏幕上面移開時觸發。
  • 135六、事件委託利用了事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。使用事件委託,只需在DOM 樹中儘可能最高的層次上添加一個事件處理程序。最適合採用事件委託技術的事件包括 click 、 mousedown 、 mouseup 、 keydown 、 keyup 和 keypress 。雖然 mouseover 和 mouseout 事件也冒泡,但要適當處理它們並不容易,並且常常須要計算元素的位置
  • 135七、第一種狀況就是從文檔中移除帶有事件處理程序的元素時。這多是經過純粹的 DOM 操做,例如使用 removeChild() 和 replaceChild() 方法,但更多地是發生在使用 innerHTML 替換頁面中某一部分的時候。若是帶有事件處理程序的元素被 innerHTML 刪除了,那麼原來添加到元素中的事件處理程序極有可能沒法被看成垃圾回收;致使「空事件處理程序」的另外一種狀況,就是卸載頁面的時候

第十四章 表單腳本

  • 140一、在以調用 submit() 方法的形式提交表單時,不會觸發 submit 事件,所以要記得在調用此方法以前先驗證表單數據
  • 140二、提交表單時可能出現的最大問題,就是重複提交表單。在第一次提交表單後,若是長時間沒有反應,用戶可能會變得不耐煩。這時候,他們也許會反覆單擊提交按鈕。結果每每很麻煩(由於服務器要處理重複的請求),或者會形成錯誤(若是用戶是下訂單,那麼可能會多訂好幾份)。解決這一問題的辦法有兩個:在第一次提交表單後就禁用提交按鈕,或者利用 onsubmit 事件處理程序取消後續的表單提交操做
  • 140三、每一個表單都有elements 屬性,該屬性是表單中全部表單元素(字段)的集合。這個 elements 集合是一個有序列表,其中包含着表單中的全部字段,例如 <input> 、 <textarea> 、 <button> 和 <fieldset> 。每一個表單字段在 elements 集合中的順序,與它們出如今標記中的順序相同,能夠按照位置和 name 特性來訪問它們。若是有多個表單控件都在使用一個 name (如單選按鈕),那麼就會返回以該 name 命名的一個NodeList
  • 140四、不少用戶可能會重複單擊表單的提交按鈕。在涉及信用卡消費時,這就是個問題:由於會致使費用翻番。爲此,最多見的解決方案,就是在第一次單擊後就禁用提交按鈕。只要偵聽 submit 事件,並在該事件發生時禁用提交按鈕便可
  • 140五、HTML5 爲表單字段新增了一個 autofocus 屬性。在支持這個屬性的瀏覽器中,只要設置這個屬性,不用 JavaScript 就能自動把焦點移動到相應字段
  • 140六、在默認狀況下,只有表單字段能夠得到焦點。對於其餘元素而言,若是先將其tabIndex 屬性設置爲1,而後再調用 focus() 方法,也可讓這些元素得到焦點。只有 Opera 不支持這種技術
  • 140七、關於 blur 和 change 事件的關係,並無嚴格的規定。在某些瀏覽器中, blur事件會先於 change 事件發生;而在其餘瀏覽器中,則剛好相反。爲此,不能假定這兩個事件總會以某種順序依次觸發,這一點要特別注意
  • 140八、要表現文本框,必須將 <input> 元素的 type 特性設置爲 "text" 。而經過設置 size 特性,能夠指定文本框中可以顯示的字符數。經過 value 特性,能夠設置文本框的初始值,而 maxlength 特性則用於指定文本框能夠接受的最大字符數
  • 140九、<textarea> 元素則始終會呈現爲一個多行文本框。要指定文本框的大小,能夠使用 rows和 cols 特性。其中, rows 特性指定的是文本框的字符行數,而 cols 特性指定的是文本框的字符列數(相似於 <inpu> 元素的 size 特性)。與 <input> 元素不一樣, <textarea> 的初始值必需要放在<textarea></textarea> 之間
  • 14十、 select() 方法,這個方法用於選擇文本框中的全部文本。在調用 select()方法時,大多數瀏覽器(Opera 除外)都會將焦點設置到文本框中。這個方法不接受參數,能夠在任什麼時候候被調用

420、 select 事件。在選擇了文本框中的文本時,就會觸發 select事件。不過,到底何時觸發 select 事件,還會因瀏覽器而異。在 IE9+、Opera、Firefox、Chrome和 Safari 中,只有用戶選擇了文本(並且要釋放鼠標),纔會觸發 select 事件。而在 IE8 及更早版本中,只要用戶選擇了一個字母(沒必要釋放鼠標),就會觸發 select 事件。另外,在調用 select() 方法時也會觸發 select 事件css

  • 14十一、取得選擇的文本。HTML5 經過一些擴展方案解決了這個問題,以便更順利地取得選擇的文本。該規範採起的辦法是添加兩個屬性: selectionStart 和 selectionEnd 。這兩個屬性中保存的是基於 0 的數值,表示所選擇文本的範圍(即文本選區開頭和結尾的偏移量)
  • 14十二、HTML5也爲選擇文本框中的部分文本提供瞭解決方案 , 即 最 早 由 Firefox 引 入 的setSelectionRange() 方法。如今除 select() 方法以外,全部文本框都有一個 setSelectionRange()方法。這個方法接收兩個參數:要選擇的第一個字符的索引和要選擇的最後一個字符以後的字符的索引(相似於 substring() 方法的兩個參數)
  • 141三、 clipboardData 對象有三個方法: getData() 、 setData() 和 clearData() 。其中, getData()用於從剪貼板中取得數據,它接受一個參數,即要取得的數據的格式; setData() 方法的第一個參數也是數據類型,第二個參數是要放在剪貼板中的文本
  • 141四、任何標註有 required 的字段,在提交表單時都不能空着。這個屬性適用於 <input> 、 <textarea>和 <select> 字段(Opera 11 及以前版本還不支持 <select> 的 required 屬性)。在 JavaScript 中,經過對應的 required 屬性,能夠檢查某個表單字段是否爲必填字段
  • 141五、HTML5 爲文本字段新增了 pattern 屬性。這個屬性的值是一個正則表達式,用於匹配文本框中的值
  • 141六、使用 checkValidity() 方法能夠檢測表單中的某個字段是否有效。全部表單字段都有個方法,若是字段的值有效,這個方法返回 true ,不然返回 false 。字段的值是否有效的判斷依據是本節前面介紹過的那些約束。換句話說,必填字段中若是沒有值就是無效的,而字段中的值與 pattern 屬性不匹配也是無效的
  • 141七、要檢測整個表單是否有效,能夠在表單自身調用 checkValidity() 方法。若是全部表單字段都有效,這個方法返回 true ;即便有一個字段無效,這個方法也會返回 false
  • 141八、對於只容許選擇一項的選擇框,訪問選中項的最簡單方式,就是使用選擇框的 selectedIndex 屬性
  • 141九、與 selectedIndex 不一樣,在容許多選的選擇框中設置選項的 selected 屬性,不會取消對其餘選中項的選擇,於是能夠動態選中任意多個項。可是,若是是在單選選擇框中,修改某個選項的 selected 屬性則會取消對其餘選項的選擇。須要注意的是,將 selected 屬性設置爲 false 對單選選擇框沒有影響
  • 1420、 contenteditable 屬性應用給頁面中的任何元素,而後用戶當即就能夠編輯該元素。document.body.contentEditable='true'

第十五章 使用canvas繪圖


第十六章 HTML5腳本編程


第十七章 錯誤處理與調試

  • 170一、在 IE7 及更早版本中,若是錯誤發生在位於外部文件的腳本中,行號一般會與錯誤所在的行號差 1。若是是嵌入在頁面中的腳本發生錯誤,則行號就是錯誤所在的行號
  • 170二、ECMA-262 第 3 版引入了 try-catch 語句,做爲 JavaScript 中處理異常的一種標準方式。也就是說,咱們應該把全部可能會拋出錯誤的代碼都放在 try 語句塊中,而把那些用於錯誤處理的代碼放在 catch 塊中。若是 try 塊中的任何代碼發生了錯誤,就會當即退出代碼執行過程,而後接着執行 catch 塊。此時, catch 塊會接收到一個包含錯誤信息的對象。與在其餘語言中不一樣的是,即便你不想使用這個錯誤對象,也要給它起個名字。這個對象中包含的實際信息會因瀏覽器而異,但共同的是有一個保存着錯誤消息的 message 屬性。ECMA-262 還規定了一個保存錯誤類型的 name 屬性;當前全部瀏覽器都支持這個屬性(Opera 9 以前的版本不支持這個屬性)。所以,在發生錯誤時,就能夠像下面這樣實事求是地顯示瀏覽器給出的消息
  • 170三、只要代碼中包含 finally 子句,那麼不管 try 仍是 catch 語句塊中的 return 語句都將被忽略。所以,在使用 finally 子句以前,必定要很是清楚你想讓代碼怎麼樣
  • 170四、TypeError 類型在 JavaScript 中會常常用到,在變量中保存着意外的類型時,或者在訪問不存在的方法時,都會致使這種錯誤。錯誤的緣由雖然多種多樣,但歸根結底仍是因爲在執行特定於類型的操做時,變量的類型並不符合要求所致
  • 170五、使用 try-catch 最適合處理那些咱們沒法控制的錯誤。假設你在使用一個大型 JavaScript 庫中的函數,該函數可能會有意無心地拋出一些錯誤。因爲咱們不能修改這個庫的源代碼,因此大可將對該函數的調用放在 try-catch 語句當中,萬一有什麼錯誤發生,也好恰當地處理它們
  • 170六、在遇到 throw 操做符時,代碼會當即中止執行。僅當有 try-catch 語句捕獲到被拋出的值時,代碼纔會繼續執行

43七、利用原型鏈還能夠經過繼承 Error 來建立自定義錯誤類型(原型鏈在第 6 章中介紹)。此時,須要爲新建立的錯誤類型指定 name 和 message 屬性html

  • 170七、說到拋出錯誤與捕獲錯誤,咱們認爲只應該捕獲那些你確切地知道該如何處理的錯誤。捕獲錯誤的目的在於避免瀏覽器以默認方式處理它們;而拋出錯誤的目的在於提供錯誤發生具體緣由的消息
  • 170八、圖像也支持 error 事件。只要圖像的 src 特性中的 URL 不能返回能夠被識別的圖像格式,就會觸發 error 事件。此時的 error 事件遵循 DOM格式,會返回一個以圖像爲目標的 event 對象
  • 170九、經過在 for 循環中添加 try-catch 語句,任何模塊初始化時出錯,都不會影響其餘模塊的初始化。在以上重寫的代碼中,若是有錯誤發生,相應的錯誤將會獲得獨立的處理,並不會影響到用戶的體驗
  • 17十、console對象具備下列方法:error(message) :將錯誤消息記錄到控制檯;info(message) :將信息性消息記錄到控制檯;log(message) :將通常消息記錄到控制檯;warn(message) :將警告消息記錄到控制檯
  • 17十一、還有一種方案是使用 LiveConnect,也就是在 JavaScript 中運行 Java 代碼。Firefox、Safari 和 Opera都支持 LiveConnect,所以能夠操做 Java 控制檯:java.lang.System.out.println("Your message")
  • 17十二、記錄消息要比使用 alert() 函數更可取,由於警告框會阻斷程序的執行,而在測定異步處理對時間的影響時,使用警告框會影響結果
  • 171三、拋出錯誤例子:throw new Error("divide(): Both arguments must be numbers.")
  • 171四、在可能發生錯誤的地方使用 try-catch 語句,這樣你還有機會以適當的方式對錯誤給出響應,而沒必要沿用瀏覽器處理錯誤的機制
  • 171五、使用 window.onerror 事件處理程序,這種方式能夠接受 try-catch 不能處理的全部錯誤(僅限於 IE、Firefox 和 Chrome)

第十八章 JavaScript 與 XML


第十九章 E4X


第二十章 JSON

  • 200一、JavaScript 字符串與 JSON 字符串的最大區別在於,JSON 字符串必須使用雙引號(單引號會致使語法錯誤)
  • 200二、JSON 中的對象要求給屬性加引號
  • 200三、JSON 中沒有變量的概念
  • 200四、JSON沒有末尾的分號
  • 200五、 eval() 函數能夠解析、解釋並返回 JavaScript 對象和數組
  • 200六、JSON 對象有兩個方法: stringify() 和 parse() 。在最簡單的狀況下,這兩個方法分別用於把JavaScript 對象序列化爲 JSON 字符串和把 JSON 字符串解析爲原生 JavaScript 值
  • 200七、將 JSON 字符串直接傳遞給 JSON.parse() 就能夠獲得相應的 JavaScript 值
  • 200八、 JSON.stringify() 除了要序列化的 JavaScript 對象外,還能夠接收另外兩個參數,這兩個參數用於指定以不一樣的方式序列化 JavaScript 對象。第一個參數是個過濾器,能夠是一個數組,也能夠是一個函數;第二個參數是一個選項,表示是否在 JSON 字符串中保留縮進
  • 200九、有時候, JSON.stringify() 仍是不能知足對某些對象進行自定義序列化的需求。在這些狀況下,能夠給對象定義 toJSON() 方法,返回其自身的 JSON 數據格式

第二十一章 Ajax 與 Comet

  • 210一、在使用 XHR 對象時,要調用的第一個方法是 open() ,它接受 3 個參數:要發送的請求的類型( "get" 、 "post" 等)、請求的 URL 和表示是否異步發送請求的布爾值
  • 210二、要發送特定的請求,必須調用 send() 方法。這裏的 send() 方法接收一個參數,即要做爲請求主體發送的數據。若是不須要經過請求主體發送數據,則必須傳入 null ,由於這個參數對有些瀏覽器來講是必需的。調用 send() 以後,請求就會被分派到服務器
  • 210三、調用 XHR 對象的 getResponseHeader() 方法並傳入頭部字段名稱,能夠取得相應的響應頭部信息。而調用 getAllResponseHeaders() 方法則能夠取得一個包含全部頭部信息的長字符串
  • 210四、使用 GET 請求常常會發生的一個錯誤,就是查詢字符串的格式有問題。查詢字符串中每一個參數的名稱和值都必須使用 encodeURIComponent() 進行編碼,而後才能放到 URL 的末尾;並且全部名-值對兒都必須由和號(&)分隔
  • 210五、 POST 請求應該把數據做爲請求的主體提交,而 GET 請求傳統上不是這樣。 POST 請求的主體能夠包含很是多的數據,並且格式不限
  • 210六、若是不設置 Content-Type 頭部信息,那麼發送給服務器的數據就不會出如今 $_POST 超級全局變量中。這時候,要訪問一樣的數據,就必須藉助 $HTTP_RAW_POST_DATA
  • 210七、與 GET 請求相比, POST 請求消耗的資源會更多一些。從性能角度來看,以發送相同的數據計, GET 請求的速度最多可達到 POST 請求的兩倍
  • 210八、XMLHttpRequest 2 級爲此定義了FormData 類型。 FormData 爲序列化表單以及建立與表單格式相同的數據(用於經過 XHR 傳輸)提供了便利
  • 210九、使用 FormData 的方便之處體如今沒必要明確地在 XHR 對象上設置請求頭部。XHR 對象可以識別傳入的數據類型是 FormData 的實例,並配置適當的頭部信息
  • 21十、支持 FormData 的瀏覽器有 Firefox 4+、Safari 5+、Chrome 和 Android 3+版 WebKit
  • 21十一、IE8 爲 XHR 對象添加了一個 timeout 屬性,表示請求在等待響應多少毫秒以後就終止。在給timeout 設置一個數值後,若是在規定的時間內瀏覽器尚未接收到響應,那麼就會觸發 timeout 事件,進而會調用 ontimeout 事件處理程序。這項功能後來也被收入了 XMLHttpRequest 2 級規範中。IE 8+是惟一支持超時設定的瀏覽器
  • 21十二、Firefox 最先引入了 overrideMimeType() 方法,用於重寫 XHR 響應的 MIME 類型。這個方法後來也被歸入了 XMLHttpRequest 2 級規範。由於返回響應的 MIME 類型決定了 XHR 對象如何處理它,因此提供一種方法可以重寫服務器返回的 MIME 類型是頗有用的
  • 211三、微軟在 IE8 中引入了 XDR( XDomainRequest )類型。這個對象與 XHR 相似,但能實現安全可靠的跨域通訊。XDR 對象的安全機制部分實現了 W3C 的 CORS 規範
  • 211四、即便瀏覽器對 CORS 的支持程度並不都同樣,但全部瀏覽器都支持簡單的(非 Preflight 和不帶憑據的)請求,所以有必要實現一個跨瀏覽器的方案。檢測 XHR 是否支持 CORS 的最簡單方式,就是檢查是否存在 withCredentials 屬性。再結合檢測 XDomainRequest 對象是否存在,就能夠兼顧全部瀏覽器了
  • 211五、第一種跨域請求技術是使用 <img> 標籤,但該方法只能用於瀏覽器與服務器間的單向通訊
  • 211六、JSONP 是 JSON with padding(填充式 JSON 或參數式 JSON)的簡寫,是應用 JSON 的一種新方法,在後來的 Web 服務中很是流行。JSONP 看起來與 JSON 差很少,只不過是被包含在函數調用中的 JSON
  • 211七、JSONP 由兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面中調用的函數。回調函數的名字通常是在請求中指定的。而數據就是傳入回調函數中的JSON數據。下面是一個典型的JSONP請求
  • 211八、JSONP 是經過動態 <script> 元素(要了解詳細信息,請參考第 13 章)來使用的,使用時能夠爲src 屬性指定一個跨域 URL。這裏的 <script> 元素與 <img> 元素相似,都有能力不受限制地從其餘域加載資源。由於 JSONP 是有效的 JavaScript 代碼,因此在請求完成後,即在 JSONP 響應加載到頁面中之後,就會當即執行
  • 211九、Ajax 是一種從頁面向服務器請求數據的技術,而 Comet 則是一種服務器向頁面推送數據的技術。Comet 可以讓信息近乎實時地被推送到頁面上,很是適合處理體育比賽的分數和股票報價
  • 2120、SSE(Server-Sent Events,服務器發送事件)是圍繞只讀 Comet 交互推出的 API 或者模式。SSE API用於建立到服務器的單向鏈接,服務器經過這個鏈接能夠發送任意數量的數據。服務器響應的 MIME類型必須是 text/event-stream ,並且是瀏覽器中的 JavaScript API 能解析格式輸出。SSE 支持短輪詢、長輪詢和 HTTP 流,並且能在斷開鏈接時自動肯定什麼時候從新鏈接
  • 212一、Web Sockets的目標是在一個單獨的持久鏈接上提供全雙工、雙向通訊。在 JavaScript 中建立了 Web Socket 以後,會有一個 HTTP 請求發送到瀏覽器以發起鏈接。在取得服務器響應後,創建的鏈接會使用 HTTP 升級從 HTTP 協議交換爲 WebSocket 協議。也就是說,使用標準的 HTTP 服務器沒法實現 Web Sockets,只有支持這種協議的專門服務器才能正常工做
  • 212二、使用自定義協議而非 HTTP 協議的好處是,可以在客戶端和服務器之間發送很是少許的數據,而沒必要擔憂 HTTP 那樣字節級的開銷。因爲傳遞的數據包很小,所以 Web Sockets很是適合移動應用。畢竟對移動應用而言,帶寬和網絡延遲都是關鍵問題。使用自定義協議的缺點在於,制定協議的時間比制定JavaScript API 的時間還要長。Web Sockets曾幾度擱淺,就由於不斷有人發現這個新協議存在一致性和安全性的問題。Firefox 4 和 Opera 11 都曾默認啓用 Web Sockets,但在發佈前夕又禁用了,由於又發現了安全隱患。目前支持 Web Sockets 的瀏覽器有 Firefox 6+、Safari 5+、Chrome 和 iOS 4+版 Safari
  • 212三、由於 Web Sockets只能經過鏈接發送純文本數據,因此對於複雜的數據結構,在經過鏈接發送以前,必須進行序列化
  • 212四、面對某個具體的用例,在考慮是使用 SSE 仍是使用 Web Sockets 時,能夠考慮以下幾個因素。首先,你是否有自由度創建和維護 Web Sockets服務器?由於 Web Socket 協議不一樣於 HTTP,因此現有服務器不能用於 Web Socket 通訊。SSE 卻是經過常規 HTTP 通訊,所以現有服務器就能夠知足需求。第二個要考慮的問題是到底需不須要雙向通訊。若是用例只需讀取服務器數據(如比賽成績),那麼 SSE 比較容易實現。若是用例必須雙向通訊(如聊天室),那麼 Web Sockets 顯然更好。別忘了,在不能選擇 Web Sockets 的狀況下,組合 XHR 和 SSE 也是能實現雙向通訊的
  • 212五、同源策略是對 XHR 的一個主要約束,它爲通訊設置了「相同的域、相同的端口、相同的協議」這一限制。試圖訪問上述限制以外的資源,都會引起安全錯誤,除非採用被承認的跨域解決方案。這個解決方案叫作 CORS(Cross-Origin Resource Sharing,跨源資源共享),IE8 經過 XDomainRequest 對象支持CORS,其餘瀏覽器經過 XHR 對象原生支持 CORS。圖像 Ping 和 JSONP 是另外兩種跨域通訊的技術,但不如 CORS 穩妥
  • 212六、Comet 是對 Ajax 的進一步擴展,讓服務器幾乎可以實時地向客戶端推送數據。實現 Comet 的手段主要有兩個:長輪詢和 HTTP 流。全部瀏覽器都支持長輪詢,而只有部分瀏覽器原生支持 HTTP 流。SSE(Server-Sent Events,服務器發送事件)是一種實現 Comet 交互的瀏覽器 API,既支持長輪詢,也支持HTTP 流
  • 212七、Web Sockets是一種與服務器進行全雙工、雙向通訊的信道。與其餘方案不一樣,Web Sockets 不使用HTTP 協議,而使用一種自定義的協議。這種協議專門爲快速傳輸小數據設計。雖然要求使用不一樣的Web 服務器,但卻具備速度上的優點

第二十二章 高級技巧

  • 220一、函數綁定能夠在特定的 this 環境中以指定參數調用另外一個函數。該技巧經常和回調函數與事件處理程序一塊兒使用,以便在將函數做爲變量傳遞的同時保留代碼執行環境
  • 220二、一個簡單的 bind() 函數接受一個函數和一個環境,並返回一個在給定環境中調用給定函數的函數,而且將全部參數原封不動傳遞過去
  • 220三、ECMAScript 5 爲全部函數定義了一個原生的 bind() 方法,進一步簡單了操做

48五、原生的 bind() 方法與前面介紹的自定義 bind() 方法相似,都是要傳入做爲 this 值的對象。支持原生 bind() 方法的瀏覽器有 IE9+、Firefox 4+和 Chromejava

  • 220四、與函數綁定緊密相關的主題是函數柯里化(function currying),它用於建立已經設置好了一個或多個參數的函數。函數柯里化的基本方法和函數綁定是同樣的:使用一個閉包返回一個函數。二者的區別在於,當函數被調用時,返回的函數還須要設置一些傳入的參數
  • 220五、JavaScript 共享的本質一直是開發人員心頭的痛。由於任何對象均可以被在同一環境中運行的代碼修改。開發人員極可能會意外地修改別人的代碼,甚至更糟糕地,用不兼容的功能重寫原生對象。ECMAScript 5致力於解決這個問題,可讓開發人員定義防篡改對象(tamper-proof object)
  • 220六、第一行代碼已經完整定義 person 對象,但第二行代碼仍然能給它添加屬性。使用Object.preventExtensions() 方法能夠改變這個行爲,讓你不能再給對象添加屬性和方法
  • 220七、雖然不能給對象添加新成員,但已有的成員則絲絕不受影響。你仍然還能夠修改和刪除已有的成員。另外,使用 Object.istExtensible() 方法還能夠肯定對象是否能夠擴展
  • 220八、密封對象不可擴展,並且已有成員的 [[Configurable]] 特性將被設置爲 false 。這就意味着不能刪除屬性和方法。要密封對象,能夠使用 Object.seal() 方法
  • 220九、凍結的對象既不可擴展,又是密封的,並且對象數據屬性的 [[Writable]] 特性會被設置爲 false 。若是定義 [[Set]] 函數,訪問器屬性仍然是可寫的。ECMAScript 5定義的 Object.freeze() 方法能夠用來凍結對象
  • 22十、除了主 JavaScript 執行進程外,還有一個須要在進程下一次空閒時執行的代碼隊列。隨着頁面在其生命週期中的推移,代碼會按照執行順序添加入隊列。例如,當某個按鈕被按下時,它的事件處理程序代碼就會被添加到隊列中,並在下一個可能的時間裏執行。當接收到某個 Ajax 響應時,回調函數的代碼會被添加到隊列。在 JavaScript 中沒有任何代碼是馬上執行的,但一旦進程空閒則儘快執行
  • 22十一、定時器對隊列的工做方式是,當特定時間過去後將代碼插入。注意,給隊列添加代碼並不意味着對它馬上執行,而只能表示它會盡快執行。設定一個 150ms 後執行的定時器不表明到了 150ms代碼就馬上執行,它表示代碼會在 150ms 後被加入到隊列中。若是在這個時間點上,隊列中沒有其餘東西,那麼這段代碼就會被執行,表面上看上去好像代碼就在精確指定的時間點上執行了。其餘狀況下,代碼可能明顯地等待更長時間才執行
  • 22十二、使用 setInterval() 建立的定時器確保了定時器代碼規則地插入隊列中。這個方式的問題在於,定時器代碼可能在代碼再次被添加到隊列以前尚未完成執行,結果致使定時器代碼連續運行好幾回,而之間沒有任何停頓。幸虧,JavaScript 引擎夠聰明,能避免這個問題。當使用 setInterval() 時,僅當沒有該定時器的任何其餘代碼實例時,纔將定時器代碼添加到隊列中
  • 221三、這種重複定時器的規則有兩個問題:(1) 某些間隔會被跳過;(2) 多個定時器的代碼執行之間的間隔可能會比預期的小
  • 221四、運行在瀏覽器中的 JavaScript 都被分配了一個肯定數量的資源。不一樣於桌面應用每每可以隨意控制他們要的內存大小和處理器時間,JavaScript 被嚴格限制了,以防止惡意的 Web 程序員把用戶的計算機搞掛了。其中一個限制是長時間運行腳本的制約,若是代碼運行超過特定的時間或者特定語句數量就不讓它繼續執行。若是代碼達到了這個限制,會彈出一個瀏覽器錯誤的對話框,告訴用戶某個腳本會用過長的時間執行,詢問是容許其繼續執行仍是中止它
  • 221五、瀏覽器中某些計算和處理要比其餘的昂貴不少。例如,DOM 操做比起非 DOM 交互須要更多的內存和 CPU 時間。連續嘗試進行過多的 DOM相關操做可能會致使瀏覽器掛起,有時候甚至會崩潰。尤爲在 IE 中使用 onresize 事件處理程序的時候容易發生,當調整瀏覽器大小的時候,該事件會連續觸發。在 onresize 事件處理程序內部若是嘗試進行 DOM 操做,其高頻率的更改可能會讓瀏覽器崩潰。爲了繞開這個問題,你能夠使用定時器對該函數進行節流
  • 221六、只要代碼是週期性執行的,都應該使用節流,可是你不能控制請求執行的速率
  • 221七、事件是一種叫作觀察者的設計模式,這是一種建立鬆散耦合代碼的技術。對象能夠發佈事件,用來表示在該對象生命週期中某個有趣的時刻到了。而後其餘對象能夠觀察該對象,等待這些有趣的時刻到來並經過運行代碼來響應
  • 221八、觀察者模式由兩類對象組成:主體和觀察者。主體負責發佈事件,同時觀察者經過訂閱這些事件來觀察該主體。該模式的一個關鍵概念是主體並不知道觀察者的任何事情,也就是說它能夠獨自存在並正常運做即便觀察者不存在。從另外一方面來講,觀察者知道主體並能註冊事件的回調函數(事件處理程序)。涉及 DOM 上時,DOM 元素即是主體,你的事件處理代碼即是觀察者
  • 221九、拖放是一種很是流行的用戶界面模式。它的概念很簡單:點擊某個對象,並按住鼠標按鈕不放,將鼠標移動到另外一個區域,而後釋放鼠標按鈕將對象「放」在這裏。拖放功能也流行到了 Web 上,成爲了一些更傳統的配置界面的一種候選方案
  • 2220、JavaScript 中的函數很是強大,由於它們是第一類對象。使用閉包和函數環境切換,還能夠有不少使用函數的強大方法。能夠建立做用域安全的構造函數,確保在缺乏 new 操做符時調用構造函數不會改變錯誤的環境對象

第二十三章 離線應用與客戶端存儲


第二十四章 最 佳 實 踐

  • 240一、變量和函數命名:變量名應爲名詞如 car 或 person;函數名應該以動詞開始,如 getName() 。返回布爾類型值的函數通常以 is 開頭,如isEnable(); 變量和函數都應使用合乎邏輯的名字,不要擔憂長度。長度問題能夠經過後處理和壓縮(本章後面會講到)來緩解
  • 240二、因爲在 JavaScript 中變量是鬆散類型的,很容易就忘記變量所應包含的數據類型。合適的命名方式能夠必定程度上緩解這個問題,但放到全部的狀況下看,還不夠。有三種表示變量數據類型的方式。第一種方式是初始化;第二種方法是使用匈牙利標記法來指定變量類型;最後一種指定變量類型的方式是使用類型註釋
  • 240三、只要應用的某個部分過度依賴於另外一部分,代碼就是耦合過緊,難於維護。典型的問題如:對象直接引用另外一個對象,而且當修改其中一個的同時須要修改另一個。緊密耦合的軟件難於維護而且須要常常重寫
  • 240四、編程實踐:尊重對象全部權;避免全局量;避免與 null 進行比較;使用常量
  • 240五、性能:注意做用域,避免全局查找,,避免 with 語句;選擇正確方法,避免沒必要要的屬性查找,優化循環,展開循環,避免雙重解釋,原生方法較快, Switch 語句較快,位運算符較快;最小化語句數,多個變量聲明,插入迭代值,使用數組和對象字面量;優化DOM交互,最小化現場更新,使用 innerHTML,使用事件委託,注意 HTMLCollection;部署,構建過程,驗證,壓縮

第二十五章 新興的API

  • 250一、requestAnimationFrame() :是一個着眼於優化 JavaScript 動畫的 API,可以在動畫運行期間發出信號。經過這種機制,瀏覽器就可以自動優化屏幕重繪操做。
  • 250二、Page Visibility API:讓開發人員知道用戶何時正在看着頁面,而何時頁面是隱藏的。
  • 250三、Geolocation API:在獲得許可的狀況下,能夠肯定用戶所在的位置。在移動 Web 應用中,這個API 很是重要並且經常使用。
  • 250四、File API:能夠讀取文件內容,用於顯示、處理和上傳。與 HTML5 的拖放功能結合,很容易就能創造出拖放上傳功能。
  • 250五、Web Timing:給出了頁面加載和渲染過程的不少信息,對性能優化很是有價值。
  • 250六、Web Workers:能夠運行異步 JavaScript 代碼,避免阻塞用戶界面。在執行復雜計算和數據處理的時候,這個 API 很是有用;要否則,這些任務輕則會佔用很長時間,重則會致使用戶沒法與頁面交互。

附錄 A

  • 常量
  • 塊級做用域及其餘做用域
  • 剩餘參數與分佈參數
  • 默認參數值
  • 生成器
  • 迭代器
  • 數組領悟
  • 解構賦值
  • 代理對象
  • 代理函數
  • 映射與集合
  • WeakMap
  • StructType
  • ArrayType
  • 類,私有成員
  • getter 和 setter
  • 繼承
  • 模塊

附錄 B

  • 選擇使用
  • 變量
  • 對象
  • 函數
  • eval()
  • eval 與 arguments
  • 抑制 this
  • 其餘變化

附錄 C

  • JavaScript 庫

附錄 D

  • JavaScript工具
相關文章
相關標籤/搜索