Doctype 是一種標準通用標記語言的文檔類型聲明,它的目的是要告訴標準通用標記語言解析器,它應該使用什麼樣的文檔類型定義(DTD)來解析文檔。 javascript
內聯元素(inline element)
* a - 錨點 * abbr - 縮寫 * acronym - 首字 * b - 粗體(不推薦) * big - 大字體 * br - 換行* em - 強調 *font - 字體設定(不推薦) * i - 斜體 * img - 圖片 * input - 輸入框 * label - 表格標籤 * s - 中劃線(不推薦) * select - 項目選擇 * small - 小字體文本 * span - 經常使用內聯容器,定義文本內區塊 * strike - 中劃線 * strong - 粗體強調 * sub - 下標 * sup - 上標* textarea - 多行文本輸入框* tt - 電傳文本* u - 下劃線* var - 定義變量
塊級元素
* address - 地址* blockquote - 塊引用* center - 舉中對齊塊* dir - 目錄列表* div - 經常使用塊級容易,也是css layout的主要標籤* dl - 定義列表* fieldset - form控制組* form - 交互表單* h1 - 大標題* h2 - 副標題* h3 - 3級標題* h4 - 4級標題* h5 - 5級標題* h6 - 6級標題* hr - 水平分隔線* isindex - input prompt* menu - 菜單列表* noframes - frames可選內容,(對於不支持frame的瀏覽器顯示此區塊內容* noscript - )可選腳本內容(對於不支持script的瀏覽器顯示此內容)* ol - 排序表單* p - 段落* pre - 格式化文本* table - 表格* ul - 非排序列表
.CSS盒子模型包含四個部分組成: css
內容、填充(padding)、邊框(border)、外邊界(margin)。w3c 盒子模型的範圍包括 margin、border、padding、content,而且 content 部分不包含其餘部分。html
ie 盒子模型的範圍也包括 margin、border、padding、content,和標準 w3c 盒子模型不一樣的是:ie 盒子模型的 content 部分包含了 border 和 pading。前端
那應該選擇哪中盒子模型呢?固然是「標準 w3c 盒子模型」了。怎麼樣纔算是選擇了「標準 w3c 盒子模型」呢?很簡單,就是在網頁的頂部加上 doctype 聲明。假如不加 doctype 聲明,那麼各個瀏覽器會根據本身的行爲去理解網頁,即 ie 瀏覽器會採用 ie 盒子模型去解釋你的盒子,而 ff 會採用標準 w3c 盒子模型解釋你的盒子,因此網頁在不一樣的瀏覽器中就顯示的不同了。反之,假如加上了 doctype 聲明,那麼全部瀏覽器都會採用標準 w3c 盒子模型去解釋你的盒子,網頁就能在各個瀏覽器中顯示一致了。java
本質上,這兩種方式都是爲了加載CSS文件,但仍是存在着細微的差異。 差異1:老祖宗的差異。link屬於XHTML標籤,而@import徹底是CSS提供的一種方式。 link標籤除了能夠加載CSS外,還能夠作不少其它的事情,好比定義RSS,定義rel鏈接屬性等,@import就只能加載CSS了。 差異2:加載順序的差異。當一個頁面被加載的時候(就是被瀏覽者瀏覽的時候),link引用的CSS會同時被加載,而@import引用的CSS會等到頁面所有被下載完再被加載。因此有時候瀏覽@import加載CSS的頁面時開始會沒有樣式(就是閃爍),網速慢的時候還挺明顯(夢之都加載CSS的方式就是使用@import,我一邊下載一邊瀏覽夢之都網頁時,就會出現上述問題)。 差異3:兼容性的差異。因爲@import是CSS2.1提出的因此老的瀏覽器不支持,@import只有在IE5以上的才能識別,而link標籤無此問題。 差異4:使用dom控制樣式時的差異。當使用javascript控制dom去改變樣式的時候,只能使用link標籤,由於@import不是dom能夠控制的。 差異5:@import能夠在css中再次引入其餘樣式表,好比能夠建立一個主樣式表,在主樣式表中再引入其餘的樣式表, 大體就這幾種差異了(若是還有什麼差異,你們告訴我,我再補充上去),其它的都同樣,從上面的分析來看,仍是使用link標籤比較好。
id 和class ,其中class能夠繼承,僞類的標籤也能夠繼承,列表ul li dl dd dt 能夠繼承,優先級就近原則,樣式定義爲最近者, 優先級比較:!important>【id>class>tag】
網頁的結構層(structural layer)由 HTML 或 XHTML 之類的標記語言負責建立。標籤,也就是那些出如今尖括號裏的單詞,對網頁內容的語義含義作出了描述,但這些標籤不包含任何關於如何顯示有關內容的信息。例如,P 標籤表達了這樣一種語義:「這是一個文本段。」 網頁的表示層(presentation layer) 由 CSS 負責建立。 CSS 對「如何顯示有關內容」的問題作出了回答。 網頁的行爲層(behavior layer)負責回答「內容應該如何對事件作出反應」這一問題。這是 Javascript 語言和 DOM 主宰的領域。 程序員
選擇器{屬性1:值1;屬性2:值2;……} web
①Trident:表明瀏覽器:IE4,IE5,IE6,IE7,IE8,IE9,Maxthon,The World,GreenBrowser,騰訊TT等。 算法
②Presto 表明瀏覽器:Opera,NDSBrowser,Wii Internet Channle,Nokia 770; chrome
③Gecko 表明瀏覽器:Netscape,Mazilla Firefox;
④Webkit 表明瀏覽器:Safari,Chrome; 編程
瀏覽器hack前綴 例如
*/ -o-transform: rotate(40deg); /* Opera瀏覽器 */ /-webkit-transform: rotate(40deg); /* Webkit內核瀏覽器 chrome ,safari */-moz-transform: rotate(40deg); /* Firefox瀏覽器 */ */-ms-transform:rotate(-40deg) ;/*IE9*/
(1)建立新節點
createDocumentFragment() //建立一個DOM片斷 createElement_x() //建立一個具體的元素 createTextNode() //建立一個文本節點
(2)添加、移除、替換、插入
appendChild() removeChild() replaceChild() insertBefore()
(3)查找
getElementsByTagName() //經過標籤名稱 getElementsByName() //經過元素的Name屬性的值 getElementById() //經過元素Id,惟一性
(4)複製節點
cloneNode() 方法,用於複製節點, 接受一個布爾值參數, true 表示深複製(複製節點及其全部子節點), false 表示淺複製(複製節點自己,不復制子節點)
1 var ul = document.getElementByIdx_x("myList"); //得到ul 2 var deepList = ul.cloneNode(true); //深複製 3 var shallowList = ul.cloneNode(false); //淺複製
在瀏覽器解析事件的時候,有兩種觸發方式,一種叫作Bubbling(冒泡),另一種叫作Capturing(捕獲)。由上圖能夠看出來,冒泡的方式效果就是當一個DOM元素的某事件例如click事件被fire時,依次它的父元素的click事件也被fire(觸發),一直傳遞到最頂層的body元素爲止。而捕獲的觸發方式正好相反,當某個元素的click事件被觸發時,先從最頂層的body元素click事件被觸發開始,一直傳遞到真正被觸發的元素爲止。
① Traditional Module
傳統方式的事件模型即直接在DOM元素上綁定事件處理器,例如—
window.onload=function(){…} obj.onmouseover=function(e){…} obj.onclick=function(){…}
首先這種方式是不管在IE仍是Firefox等其餘瀏覽器上均可以成功運行的通用方式。這即是它最大的優點了,並且在Event處理函數內部的this變量無一例外的都只想被綁定的DOM元素,這使得Js程序員能夠大大利用this關鍵字作不少事情。
至於它的缺點也很明顯,就是傳統方式只支持Bubbling,而不支持 Capturing
二、 W3C (Firefox.e.g) Event Module
Firefox等瀏覽器很堅定的遵循W3C標準來制定瀏覽器事件模型,使用addEventListener和removeEventListener兩個函數,看幾個例子—
window.addEventListener(‘load’,function(){…},false); document.body.addEventListener(‘keypress’,function{…},false); obj.addEventListener(‘mouseover’,MV,true); function MV(){…}
addEventListener帶有三個參數,第一個參數是事件類型,就是咱們熟知的那些事件名字去掉前面的’on’,第二個參數是處理函數,能夠直接給函數字面量或者函數名,第三個參數是boolean值,表示事件是否支持Capturing。
W3C的事件模型優勢是Bubbling和Capturing都支持, 而且能夠在一個DOM元素上綁定多個事件處理器,各自並不會衝突。而且在處理函數內部,this關鍵字仍然可使用只想被綁定的DOM元素。另外function參數列表的第一個位置(無論是否顯示調用),都永遠是event對象的引用。 至於它的缺點,很不幸的就只有在市場份額最大的IE瀏覽器下不可以使用這一點。
三、 IE Event Module
IE本身的事件模型跟W3C的相似,但主要是經過attachEvent和detachEvent兩個函數來實現的。依舊看幾個例子吧—
window.attachEvent(‘onload’,function(){…}); document.body.attachEvent(‘onkeypress’,myKeyHandler);
能夠發現它跟W3C的區別是沒有第三個參數,並且第一個表示事件類型的參數也必須把’on’給加上。這種方式的優勢就是能綁定多個事件處理函數在同一個DOM元素上。 至於它的缺點,爲何現在在實際開發中不多見呢?首先IE瀏覽器自己只支持Bubbling不支持Capturing;並且在事件處理的function內部this關鍵字也沒法使用,由於this永遠都只想window object這個全局對象。要想獲得event對象必須經過window.event方式,最後一點,在別的瀏覽器中,它顯然是沒法工做的。
最後我在推薦兩個必須知道的IE和W3C標準的區別用法吧—
一、 當咱們須要阻止瀏覽器某DOM元素的默認行爲的時候在W3C下調用e.preventDefault(),而在IE下則經過window.event.returnValue=false來實現。
二、當咱們要阻止事件冒泡的時候,在W3C標準裏調用e.stopPropagation(),而在IE下經過設置window.event.cancelBubble=true來實現。
(一)對象冒充
function A(name){ this.name = name; this.sayHello = function(){alert(this.name+」 say Hello!」);}; } function B(name,id){ this.temp = A; this.temp(name); //至關於new A(); delete this.temp; //防止在之後經過temp引用覆蓋超類A的屬性和方法 this.id = id; this.checkId = function(ID){alert(this.id==ID)};}
當構造對象B的時候,調用temp至關於啓動A的構造函數,注意這裏的上下文環境中的this對象是B的實例,因此在執行A構造函數腳本時,全部A的變量和方法都會賦值給this所指的對象,即B的實例,這樣子就達到B繼承了A的屬性方法的目的。以後刪除臨時引用temp,是防止維護B中對A的類對象(注意不是實例對象)的引用更改,由於更改temp會直接致使類A(注意不是類A的對象)結構的變化。
咱們看到了,在Js版本更新的過程當中,爲了更方便的執行這種上下文this的切換以達到繼承或者更加廣義的目的,增長了call和apply函數。它們的原理是同樣的,只是參數不一樣的版本罷了(一個可變任意參數,一個必須傳入數組做爲參數集合)。這裏就以call爲例子,解釋一下用call實現的對象冒充繼承。
function Rect(width, height){ this.width = width; this.height = height; this.area = function(){return this.width*this.height;}; } function myRect(width, height, name){ Rect .call(this,width,height); this.name = name; this.show = function(){ alert(this.name+」 with area:」+this.area()); } }
關於Call方法,官方解釋:調用一個對象的一個方法,以另外一個對象替換當前對象。
call (thisOb,arg1, arg2…)
這也是一種對象冒充的繼承,其實在call方法調用的時候發生的事情也是上下文環境變量this的替換,在myRect函數體中this確定是指向類myRect對象的實例了,然而用這個this做爲上下文環境變量調用名字叫Rect方法,即類Rect的構造函數。因而此時調用Rect時候對this的賦值屬性和方法都其實是對一個myRect的對象進行。因此說盡管call和apply並非僅僅爲了繼承而新增的方法,但用它們能夠模擬繼承。
對象冒充繼承就是這麼一回事,它能夠實現多重繼承,只要重複作這一套賦值的流程就能夠了。不過目前真正大規模使用得並很少,爲何呢?由於它有一個明顯的性能缺陷,這就要說道OO的概念了,咱們說對象是成員+成員方法的集合,構造對象實例的時候,這些實例只須要擁有各自的成員變量就能夠了,成員方法只是一段對變量操做的可執行文本區域而已,這段區域不用爲每一個實例而複製一份,全部的實例均可以共享。如今回到Js利用對象冒充模擬的繼承裏,全部的成員方法都是針對this而建立的,也就是所全部的實例都會擁有一份成員方法的副本,這是對內存資源的一種極度浪費。其它的缺陷好比說對象冒充沒法繼承prototype域的變量和方法就不用提了,筆者認爲前一個致命缺陷就已經足夠。不過,咱們仍是須要理解它,特別是父類的屬性和方法是如何繼承下來的原理,對於理解Js繼承很重要。
(二)原型方式
第二種繼承方式是原型方式,所謂原型方式的繼承,是指利用了prototype或者說以某種方式覆蓋了prototype,從而達到屬性方法複製的目的。其實現方式有不少中,可能不一樣框架多少會有一點區別,可是咱們把握住原理,就不會有任何不理解的地方了。看一個例子(某一種實現):
function Person(){ this.name = 「Mike」; this.sayGoodbye = function(){alert(「GoodBye!」);}; } Person.prototype.sayHello = function(){alert(」Hello!」);}; function Student(){} Student.prototype = new Person();
關鍵是對最後一句Student原型屬性賦值爲Person類構造的對象,這裏筆者解釋一下父類的屬性和方法是如何copy到子類上的。Js對象在讀取某個對象屬性的時候,老是先查看自身域的屬性列表,若是有就返回不然去讀取prototype域(每一個對象共享構造對象的類的prototype域全部屬性和方法),若是找到就返回,因爲prototype能夠指向別的對象,因此Js解釋器會遞歸的去查找prototype域指向對象的prototype域,直到prototype爲自己,查找變成了一種循環,就中止,此時還沒找到就成undefined了。
這樣看來,最後一句發生的效果就是將父類全部屬性和方法鏈接到子類的prototype域上,這樣子類就繼承了父類全部的屬性和方法,包括name、sayGoodbye和sayHello。這裏與其把最後一句當作一種賦值,不如理解成一種指向關係更好一點。這種原型繼承的缺陷也至關明顯,就是繼承時父類的構造函數時不能帶參數,由於對子類prototype域的修改是在聲明子類對象以後才能進行,用子類構造函數的參數去初始化父類屬性是沒法實現的,以下所示:
function Person(name){ this.name = name; } function Student(name,id){ this.id = id; } Student.prototype = new Person(this.name);
兩種繼承方式已經講完了,若是咱們理解了兩種方式下子類如何把父類的屬性和方法「抓取」下來,就能夠自由組合各自的利弊,來實現真正合理的Js繼承。下面是我的總結的一種綜合方式:
function Person(name){ this.name = name; } Person.prototype.sayHello = function(){alert(this.name+「say Hello!」);}; function Student(name,id){ Person.call(this,name); this.id = id; } Student.prototype = new Person(); Student.prototype.show = function(){ alert(「Name is:」+ this.name+」 and Id is:」+this.id); }
總結就是利用對象冒充機制的call方法把父類的屬性給抓取下來,而成員方法儘可能寫進被全部對象實例共享的prototype域中,以防止方法副本重複建立。而後子類繼承父類prototype域來抓取下來全部的方法。如想完全理清這些調用鏈的關係,推薦你們多關注Js中prototype的constructor和對象的constructor屬性