回國半個月的準海帶,今天體驗了一下第一場技術面試。首先是一套題目,30分鐘左右的時間根據本身的水平選難題回答,答完以後以後才進行面試。面試官問了不少基礎問題,也不少沒能回答上。略受打擊。。。php
後悔試題沒拍照,根據回憶整理:css
1.上下左右居中html
這個題面試前纔看過,但問到仍是不能說清楚,仍是基礎有硬傷
思路爲絕對定位,在寬高必定的狀況下,上下設置爲50%。以後設置margin爲負值,margin-top和margin-left爲自身高度和寬度的一半,將位置拉回中間。css3
.content{ position: absolute; width:400px; height:400px; top:50%; left:50%; margin:-200px 0 0 -200px; border:1px solid #008800; }
2.兩欄,左邊固定100px,右邊自適應git
其實作佈局這個用的最多最多見,我也說的蠻自信的,惋惜我把兩個思路的屬性說混了。
第一個思路是左邊用float:left,右邊用margin-left爲左欄的寬度。github
*{ margin: 0; padding: 0; } .left{ float:left; width:100px; border: solid #999 1px; } .right{ margin-left: 100px; border: solid #777 1px; }
第二個思路略複雜,右欄width:100%,float:left,可是這樣就會超出屏幕的寬度,因而用負值margin拉回來。但這就出現另外一個問題,因爲右欄縮到左欄裏,因此左欄會遮蓋右欄的一部分,因此在右欄內部再鑲嵌一層,margin-left爲左欄的寬度web
*{ margin: 0; padding: 0; } .left{ float:left; width:100px; border: solid #999 1px; margin-right: -100%; } .right{ float:left; width:100%; border: solid #777 1px; } .content{ margin-left: 100px; }
補充:第三種方式是在整理下面題目的時候發現的,用display:table-cell的自適應。
思路仍是,由於table-cell的自適應,將右欄設的儘量的大。面試
*{ margin: 0; padding: 0; } .left{ float:left; width:100px; border: solid #999 1px; } .right{ display: table-cell; width:3000px; border: solid #777 1px; }
3.盒模型算法
盒模型能夠幫助塊級元素的定位和計算面積,簡單來講W3C的盒模型包括content、padding、border。而IE得盒模型則有些不一樣,表如今設置寬高的時候,W3C模型下只包含content區域,而IE包括全部區域。
這樣,在IE下,設置了寬高以後能夠很放心的設定padding,可是對於W3C模型下,設置了寬高以後還要計算padding和border的區域。所以有一個方法叫作box-sizing:border-box。border-box將border和padding區域一同算進設定的寬高內。這樣的話添加以下代碼,就能夠設定padding而用不擔憂超出設置區域。編程
div{ box-sizing:border-box; -moz-box-sizing:border-box; /* Firefox */ -webkit-box-sizing:border-box; /* Safari */ }
4.幾種方法生成三個並排的大小相等的元素
這個問題讓我有點蒙,首先想到的是三個元素都用百分比控制
*{ margin: 0; padding: 0; } .left,.right,.middle{ float:left; width:33.3% }
其實還有能夠用display:inline-block。回家之後嘗試了一下,發現問題是若是這幾個元素沒有在代碼裏寫在一行,那麼最後展示出來的是最後一個元素會被擠到下面一行。
大神男朋友告訴我hack方法爲:
margin-right: -4px//能夠按照實際調整。
關於inline-block縫隙,推薦一篇文章:去除間距
還有一個方法爲tabel-cell,這種方法就是將每個元素設置的儘量的大,但因爲自適應的特性,這三個元素仍是會乖乖地等分的排在一行裏。
*{ margin: 0; padding: 0; } .left,.middle, .right{ display:table-cell; width:3000px; }
接着昨天的繼續補充
5.CSS3的新特性用過哪些
對於我來講最經常使用固然是border-radius,讓圓角成爲方便的存在。
然而他問第二個問題:怎樣將方的經過圓角變成圓的?
其實只要
border-radius:50%;
就行了。惋惜當時我怕這個不能用百分比,因而說若是50的寬高,半徑爲25就好。其實這個也沒錯啦,但也看的出我基礎不紮實。
除此以外,box-shadow也是咱經常使用的屬性之一。設置水平、垂直的位移,陰影的模糊、尺寸還有顏色,就能夠爲元素添加陰影。
box-shadow: 2px 2px 3px #777;
而後我也提了一下border-image這個好用又漂亮的屬性。經過設置圖片路徑,圖片的切割方式、還有邊框的寬度、溢出,以及平鋪或拉伸等呈現方式,能夠作出一個漂亮精緻的邊框。
border-image: url(border-image.png) 30/10px/10px round;
關於border-image的每一項屬性的用法和限制,能夠參考我大神男朋友的文章CSS 3 border-image 屬性詳解
面試官還問到了動畫:transition、transform和animation的區別?
惋惜我目前並無用CSS作過動畫【攤手。。
他專門問到了這個問題,說明CSS3的動畫是應用較多的,回來馬上學習。
transform是指轉換,能夠將元素移動、旋轉、傾斜、拉伸。
translate(),從當前位置移動到由給定left和top值的位置。這個例子中,div向右下移動,若是想要往左上移動,則要設置爲負值。
div{ transform: translate(50px,100px); -ms-transform: translate(50px,100px); /* IE 9 */ -webkit-transform: translate(50px,100px); /* Safari and Chrome */ -o-transform: translate(50px,100px); /* Opera */ -moz-transform: translate(50px,100px); /* Firefox */ }
rotate(),將元素旋轉到給定角度,單位爲deg(degree角度),在這個例子中爲順時針30度。負值的話爲逆時針旋轉。
div{ transform: rotate(30deg); -ms-transform: rotate(30deg); /* IE 9 */ -webkit-transform: rotate(30deg); /* Safari and Chrome */ -o-transform: rotate(30deg); /* Opera */ -moz-transform: rotate(30deg); /* Firefox */ }
skew() ,將元素傾斜到給定角度,單位也是deg,分別圍繞着X軸和Y軸翻轉。這個例子中,在X軸順時針翻轉30度,Y軸順時針翻轉20度,負值爲逆時針翻轉。
div{ transform: skew(30deg,20deg); -ms-transform: skew(30deg,20deg); /* IE 9 */ -webkit-transform: skew(30deg,20deg); /* Safari and Chrome */ -o-transform: skew(30deg,20deg); /* Opera */ -moz-transform: skew(30deg,20deg); /* Firefox */ }
scale(),將元素拉伸到指定的倍數,一樣設定了X與Y兩個方向。這個例子中把寬度拉伸2倍,高度拉伸4倍。有意思的是,負值不是縮小,而是翻轉,既水平翻轉和垂直翻轉。
div{ transform: scale(2,4); -ms-transform: scale(2,4); /* IE 9 */ -webkit-transform: scale(2,4); /* Safari 和 Chrome */ -o-transform: scale(2,4); /* Opera */ -moz-transform: scale(2,4); /* Firefox */ }
transform並無變化的過程,而是直接生成最終效果。transform還有3D方法,就是多了一個Z軸(Opera不支持)
transition是指過渡,能夠動畫般顯示出一個從樣式到樣式之間的過渡。
上面說過transform沒有變化的過程,這樣一來就能夠動畫顯示出各類酷炫的效果。
transform的屬性包括一個你設定過渡的CSS屬性,持續時間,時間曲線還有過渡開始的時間。
比較麻煩的寫法,每一項屬性單獨寫:
div{ transition-property: width; transition-duration: 1s; transition-timing-function: linear; transition-delay: 2s; /* Firefox 4 */ -moz-transition-property:width; -moz-transition-duration:1s; -moz-transition-timing-function:linear; -moz-transition-delay:2s; /* Safari 和 Chrome */ -webkit-transition-property:width; -webkit-transition-duration:1s; -webkit-transition-timing-function:linear; -webkit-transition-delay:2s; /* Opera */ -o-transition-property:width; -o-transition-duration:1s; -o-transition-timing-function:linear; -o-transition-delay:2s; }
簡單的寫法就是將屬性都寫在transition中。下面例子中包括了以前咱們將transform的旋轉,效果比較酷炫。(背景用色有點小私心,不過過渡很漂亮
div{ width:100px; height:100px; background:lavender; transition:width 2s, height 2s, background 2s; -moz-transition:width 2s, height 2s, -moz-transform 2s; /* Firefox 4 */ -webkit-transition:width 2s, height 2s, -webkit-transform 2s, background 2s; /* Safari and Chrome */ -o-transition:width 2s, height 2s, background 2s, -o-transform 2s; /* Opera */ } div:hover{ width:200px; height:200px; background:LightSeaGreen; transform:rotate(180deg); -moz-transform:rotate(180deg); /* Firefox 4 */ -webkit-transform:rotate(180deg); /* Safari and Chrome */ -o-transform:rotate(180deg); /* Opera */ }
animation,用@keyframes規則作動畫效果。
若是說transition是過渡中的動畫效果,那麼animation就是專門作動畫的。transition是animation的簡化,是當屬性發生變化的時候,觸發過渡動畫。就是上面例子中hover的時候,css的屬性變化了,那麼在transition裏面綁定過得屬性動畫過渡過去。
animation就複雜多了:@keyframes能夠有from to,也能夠是百分比表示時間幀。
from-to
@keyframes myfirst{ from {background: lavender;} to {background: LightSeaGreen;} }
百分比
@keyframes myfirst{ 0% {background: purple;} 25% {background: lavender;} 50% {background: cyan;} 75% {background: LightSeaGreen;} 100% {background:purple;} }
而後再將這個@keyframes綁定到一個元素上。
animation提供了更多屬性,包括@keyframes名字、持續時間、速度曲線、開始時間、播放次數等。
div{ animation: myfirst 5s linear 2s infinite alternate; /* Firefox: */ -moz-animation: myfirst 5s linear 2s infinite alternate; /* Safari 和 Chrome: */ -webkit-animation: myfirst 5s linear 2s infinite alternate; /* Opera: */ -o-animation: myfirst 5s linear 2s infinite alternate; }
有了這幾個屬性,css能夠在不少時候取代flash和動圖了。
可能由於筆試中JS題目較多,因此面試的時候沒有問太多。
1.優化代碼,事件委託
筆試的題目上給了一段代碼讓我優化。具體代碼記不清,大概是獲取的元素,而後循環爲每個添加mouseover和mouseout事件。
var elementList=document.querySelectorAll("a"); var listLen=elementList.length; function handler (element,color){ return function(){ element.style.color=color; }; } //添加事件方法 function addEvent(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); } else if(element.attachEvent){ element.attachEvent("on"+type,handler); } } //循環爲元素添加事件 for(i=0;i<listLen;i++){ addEvent(elementList[i],"mouseover",handler(elementList[i],"red")); addEvent(elementList[i],"mouseout",handler(elementList[i],"black")); }
而後面試官又問我爲何事件委託效率更高
仍是基礎硬傷,我只是大概知道什麼是事件委託,對於原理還不瞭解。因而回來又查參考書《Javascript高級程序設計》
???????????事件委託利用了事件冒泡,指定??????一個事件處理程序,就能夠管理某一個類型的全部事件。
書上解釋,在DOM樹中儘可能高的層次上添加一個事件處理程序。那麼在他的子孫元素中的事件,最終都會冒泡到這個層次中。例如,列表裏有兩個項目,咱們不要分別設置每個項目點擊時的事件,而是在上層中創建事件委託。
<ul id="link"> <li id="home">首頁</li> <li id="resume">簡歷</li> </ul>
var link = document.querySelector("#link"); //添加事件 function addEvent(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); } else if(element.attachEvent){ element.attachEvent("on"+type,handler); } } //獲取事件對象,由於奇葩的IE,事件對象要用window.event function getEvent(event){ return event ? event : window.event; } //獲取事件目標 function getTarget(event){ return event.target || event.srcElement; } //爲外層ul添加事件委託 addEvent(link,"click",function(event){ event = getEvent(event); var target = getTarget(event); //爲每個li添加事件 switch(target.id){ case "home": target.innerHTML="首頁,<a href='http://myj.name/'>Welcome to my home</a>" break; case "resume": location.href = "http://katherina-miao.github.io/resume/"; break; } })
2.添加一個相似email中checklist的雙向聯動
起初,個人心裏是崩潰的。。。
這個題剛開始都沒搞清楚是作什麼的,一直到作完整個卷子我才又回頭看了看這個題。時間有限,都沒來得及想就往紙上寫。
其實這個題是讓我作一個相似email裏選擇發件人的東西,勾選的時候添加到發件人,取消勾選的時候從發件人裏面刪除。因爲是雙向聯動,所以要在發件人裏點擊的時候能夠刪除,而且取消勾選。好像說的有點亂,看下面代碼。
其實主要仍是事件綁定,而後添加節點,改變屬性。
<div class="container"> <div class="showbox"></div> <input type="checkbox" name="email" value="i@myj.name">Kathy</input> <input type="checkbox" name="email" value="i@zjy.name">Visper</input> </div>
var emails=document.querySelectorAll("[name=email]"); var showBox=document.querySelector(".showbox"); var length=emails.length; //添加事件 function addEvent(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); } else if(element.attachEvent){ element.attachEvent("on"+type,handler); } } //循環,爲每一個checkbox添加事件 for(var i=0;i<length;i++){ addEvent(emails[i],"click",function(){ //判斷是否被選中 if(this.checked){ var Emailvalue = this.value; var newBtn=document.createElement("input"); newBtn.setAttribute("type","button"); newBtn.value=Emailvalue; showBox.appendChild(newBtn); } //若取消勾選,則刪除相應的button else{ var Emailvalue = this.value; var emailBtn=document.querySelector("[type=button][value='"+Emailvalue+"']"); showBox.removeChild(emailBtn); } //每次從新調用以更新button startBtn(); }) } //獲取button列表,爲button添加事件 function startBtn(){ var emailBtn=document.querySelectorAll("[type=button]"); if(emailBtn.length){ for(var i=0;i<emailBtn.length;i++){ addEvent(emailBtn[i],"click",function(){ var btnvalue=this.value; var cancelChoose=document.querySelectorAll("[value='"+btnvalue+"']"); //刪除button並取消勾選相應checkbox for(var j=0;j<cancelChoose.length;j++){ if(cancelChoose[j].getAttribute("type")=="button"){ showBox.removeChild(cancelChoose[j]); } else if(cancelChoose[j].getAttribute("type")=="checkbox"){ cancelChoose[j].checked=false; } } }) } } }
3.Array的方法
面試官問到Array有幾種方法,這個我在面試前曾經簡單整理過,因此感受回答也比較滿意。
isArray(),判斷是否爲Array類型。
join(),將Array類型轉換爲字符串類型,並用join內的符號間隔開。
隊列,棧的用法
push(),將數據項放到數組的後面。
pop(),將數組的最後一項刪除並返回。
shift(),將數組的第一項刪除並返回。
unshift(),將數據項放到數組的前面。
重排序的方法
reverse(),將數組逆序排列。
sort(),將數組由小到大排列。默認是按照字符串比較,也就是說15比5小。要按照數字排列的話,要設定方法:
var numlist = [0, 5, 15, 20, 10]; function compare (value1, value2){ value2-value1; } var listsort = numlist.sort(compare); alert( listsort );//0, 5, 10, 15, 20 按照數值從小到大
操做Array的方法
concat(),在原有meat數組上建立新數組
slice(),截取從指定位置開始到結束爲止(不包含結束位置)的數組項賦給新數組,若是沒有第二個參數,則截取從指定位置開始到結束的數組項賦給新數組
splice(),從指定位置(第一個參數)刪除指定個數(第二個參數)並插入指定項目(’第三個參數」)
位置方法
indexOf(),從前向後查找位置索引。
lastIndexOf(),從後向前查找位置索引。
這兩個方法支持第二個參數,既指定位置而後按照方法向前或向後查找位置。
遍歷方法
every()中,每一項運行給定函數,每一項都返回true,??則返回true。
filter()中,每一項運行給定函數,返回true的項。
forEach()中,每一項運行給定函數,無返回。
map()中,每一項運行給定函數,返回調用結果組成的數組。
some()中,每一項運行給定函數,任意一項返回true,?則返回true。
????????歸併方法
reduce()?和reduceRight()都接受四個參數:前一個值,當前值,索引和數組對象。
reduce()是從左向右歸併,當第一個值和第二個值運行過以後,結果將做爲下一次運行的前一個值。
reduceRight()則是從右向左,歸併方式與reduce()同樣。??
算法題就一個,給定字符串「abcba」,處理獲得第一個不重複字母。
對算法實在只是瞭解個皮毛,因此這個問題估計最後仍是寫錯了。回來後本身寫了一個,能夠獲得答案,但也不知道是否是最優。
思路是首先將字符轉換成數組,而後從小到大排序,而後循環對每個數組項比較先後。由於曾經排序,若是是不重複的那麼先後應該都與它不一樣。
var letterString="abcba"; var letterArray=Array.prototype.slice.apply(letterString); var arrayLen=letterArray.length; var sortArray=letterArray.sort(); for(var i=0;i<arrayLen;i++){ if(sortArray[i]!=sortArray[i+1]&&sortArray[i]!=sortArray[i-1]){ alert(sortArray[i]); } }
1.AJAX過程,AJAX中如何區分get和post,get和post的區別
面試官在這個方面一氣兒問了三個問題,可能由於我沒一個問題都沒能答的全面。
AJAX算是聽人說的最多的一個技術,無需加載整個頁面的狀況下進行局部更新。
再用AJAX技術與服務器交換數據時,首先建立一個XMLHttpRequest對象,在特立獨行的IE裏是ActiveXObject。
接着咱們用open()方法和send()方法,使用get和post會有些區別。而後,請求會發送給服務器,服務器會響應觸發onreadystatechange事件,當readyState=4(請求完成)且status=200時,說明服務器已經就緒。而後用responseText或responseXML屬性去得到字符串或XML格式的數據。
var xmlhttp; if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else{ //奇葩的IE五、6 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET","response.php",true); xmlhttp.send(); xmlhttp.onreadystatechange=function(){ if (xmlhttp.readyState==4 && xmlhttp.status==200){ document.getElementById("showBox").innerHTML=xmlhttp.responseText; } }
在AJAX中區別get和post,就要詳談open()方法和send()方法。
get請求經常使用於向服務器查詢信息。
在get請求中,open()的第一個參數爲「get」,第二個參數爲URL,第三個參數爲是否爲異步。因爲get請求的URL中一般帶有參數,這些參數必需要使用encodeURIComponent()方法進行編碼,不然會有格式錯誤。這樣send()方法內部的參數能夠傳入null,傳入的參數也會轉到URL中。
post請求經常使用於向服務器提交信息。
在post請求中,open()的第一個參數爲「post」,URL中不含有參數,第三個參數同樣。post請求的send()方法中須要傳入提交數據,可使用XML或者字符串。在提交表單時,首先要設定請求頭部的Content-Type爲 application/x-www-form-urlencoded。
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
而後將傳入的表單信息序列化,方便後端的程序獲取數據。對於表單數據序列化,FormData對象能夠直接放入send()內:
<form id=「user-info」> 用戶名:<input type="text" name="username"/> 年齡:<input type="text" name="年齡"/> </form>
var form = document.getElementById("user-info"); xhr.send(new FormData(form));
前面提過,get方式中url包含參數,而post中url是「乾乾淨淨」的。由於用處不一樣,post在提交內容的時候沒有大小限制。並且post在發送時有內容體,那些提交的信息放在內容體內。
2.JSONP 跨域的特性
說實話我只在用JQuery的時候用過JSONP,只知道能夠跨域,但不知道爲何能夠。因此在被問到的時候,腦子又是一蒙。
因爲跨域安全策略,XMLHttpRequest不能跨域請求,這是AJAX的一個主要限制。
JSONP是經過<script>元素。由於咱們知道,<script>能夠跨域引用js文件。返回的數據格式爲JSON,建立一個回調函數來相應返回的數據。
var script = document.createElement("script"); script.src = "http://pvoutput.org/service2v?Apikey=123&SystemID=123&callback=handler」; document.body.appendChild(script); //回調函數 function handler(response){ var responseContent={ diatotime:response.datetime, usedEnergy:response.used.Energy, … } return responseContent; }
除了JSONP,用img標籤也能夠跨域通訊。
var img = new Image(); img.src = "http://www.example.com/id=123」;
CORS是跨域請求的另外一個方法。在IE瀏覽器中爲XDomainRequest對象,而在其餘瀏覽器中則繼續用XMLHttpRequest。區別在於,XDomainRequest對象的open()只有兩個參數:請求類型和URL,由於都是異步執行。而其餘瀏覽器在使用open()時,URL要使用絕對路徑,既能夠跨域請求。
3.提升網頁性能的方法
由於剛剛問完AJAX,因此首先反應的是使用AJAX部分刷新。而後我想到了CSS精靈,將小圖片放在一塊兒減小HTTP請求。而後想到將script和css從外部引入,而後script放在文檔底部。
除此以外,總結一下:在內容上壓縮,在請求上減小。壓縮圖片、腳本和CSS,使用CSS精靈,優化圖片,儘可能使用<link>引用CSS。在請求上避免重定向,儘可能使用AJAX儘可能使用GET請求。
在優化性能方面,我沒什麼研究,仍是因爲對底層原理不熟【汗。。
此次的面試經歷整理了一天多,一是由於實在是基礎差,每一題都要查資料,編程題要本身試,二是要激勵本身。由於本身是很懶的人,不喜歡上網找文章資料。此次面試算是一個鞭策,將本身漏洞補起來。
但願各路大神評論補充!!本菜鳥道謝~~