前言
時間過的真快,不知不覺就到年底了。問問自己,這一年你對自己的工作滿意嗎? 評價標準是什麼呢?當然是馬雲的那兩條準則了:錢給到了嗎?乾的爽嗎?如果答案都是no,那麼,你準備好跳槽了嗎?
為了應對年後跳槽高峰的到來,從現在開始我要把基礎過一遍了。從網上搜集的面試題入手,儘量全面的覆蓋到前端的基礎知識。為年後的面試提前熱身~雖然本人也不是什麼麵霸,沒有什麼面試經驗,但把基礎打紮實是永遠不會錯的,所以不嫌麻煩不嫌重複勞動,我會收集一些簡單基礎的面試題,從中提煉出相關的前端知識,然後分析加以記錄。大概算了算,只要勤快點,從現在開始一直積累到年後,應該也能小有收穫~
另外還想說一下我對原生js的看法,也是最近產生的。隨著IE6、7、8的逐漸淘汰,ES5的普及,我們已經可以在ES5的標準上進行全面開發了。照這個潮流來看,jQuery似乎要被沒落了,因為它的主要工作就是做低版本IE的相容處理。我是jQuery的嚴重依賴者,如果哪天jQuery真的消失了,豈不連程式碼也不會寫了。真令人擔憂,所以今後要重視原生js了,能不用jq的地方就不用。隨著這次總結基礎知識,我也準備把原生js好好複習一遍,為未來早做打算。
正題
說到面試題,你最怕什麼樣的呢?我最怕的是題目只有一句話的,越短越難,比如:如何用js操作DOM元素。
這道題簡單嗎?,其實不然。DOM操作包括元素的建立、查詢、新增、移動、複製、刪除,每種操作又可以延伸出很多問題。如果你常年使用jq或其他框架,原生的寫法可能早就忘了。所以,我需要用一篇文章來描述清楚這個問題。
建立新元素
document.createElement(elemengTagName)用來建立一個元素,返回該新建元素的引用。需要注意引數是標籤的名稱。在jq中我們可以這樣建立一個元素
var node = $('<div>'); var node2 = $('<span id="s"></span>');
使用原生的我們必須傳入元素的標籤名稱,不能像jq中那麼靈活。如:
var node = document.createElement('div');
新增新元素
有兩個方法可以向DOM樹中新增新元素,分別是appendChild(newElement)和insertBefore(newElement,beforeWhichElement)。
appendChild向一個元素新增子節點,追加在尾部,如在body中追加一個元素:
var node = document.createElement('div'); node.innerHTML = '新新增的節點'; document.body.appendChild(node);
insertBefore也是向一個元素新增子節點,不過可以指定新增在哪個子節點的前面,如果不指定第二個引數,會預設新增到最後,即與appendChild效果一樣。使用方法如下:
var node = document.createElement('div'); node.innerHTML = '新插入的節點'; var list = document.getElementById('list'); var item1 = document.getElementById('item1'); list.insertBefore(node,item1);
會在list的子元素item1前面插入新建立的元素node。原生js沒有像jq的prepend那樣可以從頭部新增子節點的方法。
移動元素
移動元素在DOM樹中的位置還是比較常見的需求。完成元素的移動不需要新的方法,還是使用上面的appendChild和insertBefore,只不過操作的元素不是新建立的,而是從已有節點中選擇你需要移動的。例如交換兩個元素的位置:
var item1 = document.getElementById('item1'); var item2 = document.getElementById('item2'); list.insertBefore(item2,item1);//把item2插入到item1前面
使用appendChild也是同樣的道理。如:
var item3 = document.getElementById('item3'); var s = document.getElementById('some'); item3.appendChild(s);//把id為some的元素移動到item3下
複製元素
元素的複製使用cloneNode(cloneChildNodes)方法,引數為boolean型別,表示是否克隆子元素。與jq的clone方法不同的時,原生的無法克隆元素上繫結的事件監聽器。使用方法如下:
var s = document.getElementById('some'); var sclone = s.cloneNode(true);
刪除元素
使用removeChild(element)方法來刪除元素,需先找到父元素,然後刪除其子元素,如下:
var list = document.getElementById('list'); var item1 = document.getElementById('item1'); list.removeChild(item1);
查詢元素
查詢元素的內容稍多一點。jq提供了強大的選擇器,這也是它的核心之一。離開了jq,我們還是要明白如何利用原生js來選擇到你所需的元素。getElementById(id)不多說了,getElementsByTagName(tagName)返回符合元素的陣列。除此之外,我們還需知道一個元素都有哪些指標可以訪問到其他元素。概括一下,主要包括以下指標:
- parentNode:指向父節點
- childNodes:指向所有子節點,是一個陣列
- previousSibling:指向前一個兄弟節點
- nextSibling:指向後一個兄弟節點
- firstChild:指向第一個子節點
- lastChild:指向最後一個子節點
使用如下:
var item2 = document.getElementById('item2'); var parentNode = item2.parentNode; var childNodes = item2.childNodes; var previousSibling = item2.previousSibling; var nextSibling = item2.nextSibling; var firstChild = item2.firstChild; var lastChild = item2.lastChild; console.log(parentNode,childNodes,previousSibling,nextSibling,firstChild,lastChild);
你可能覺得這比起jq的選擇器簡直差遠了。告訴你一個好訊息,現在可以有更強大的東西用了,那就是querySelector和querySelectorAll,這兩個方法是ES5中新增的,他們的作用就想jq的選擇器一樣,你可以使用像css風格那樣的描述來選擇所需的元素,是不是很爽!比如:
document.querySelector('#list');//選擇id為list的元素 document.querySelectorAll('.green');//選擇class為green的元素,返回元素的陣列
兩者的區別你可看出來了,querySelector只會返回一個元素,如果匹配到多個就返回第一個。而querySelectorAll會返回所有匹配的元素陣列。有了這兩個原生的js方法,你是不是覺得jQuery的沒落不遠了呢?
結束
本篇的記錄到此結束,當以後面試問到DOM操作時,就可以應付的過來了。不親手敲一下原生的程式碼真是忘了不少呢。不過有一點是本篇沒有涉及到的,那就是DOM操作的瀏覽器相容性。說實話這塊的知識我也沒有真實遇到過,都是在jq的關照下一路走來的。故本篇只記錄一些淺層次的東西了。