【web前端面試題整理01】各位加班累了吧,來做點前端面試題吧


前言

最近小葉子有點疲憊,主要是在外地工作生活上不太適應,吃一樣的東西,我居然會拉肚子,而且是一個星期一個星期的。。。。

臉上長了一個豆豆一個星期還沒消,我那個去啊。

昨天上午上班后,本來想繼續研究javascript方面的東西的,但是下午要開會,結果一開就是4.5小時,哎喲,我那個怎么感覺很累啊,

明明是坐着的啊,開完會腰酸背痛的,回來吃過飯,本來想接着學習,卻迷迷糊糊的睡着了......

按照進度我們本來想要開始做小窗口的,但是也碰到點問題,除了各大微博,其它數據全部是RSS,與我想象的數據源不一樣,所以這塊還需要點時間,加之今天起來還是有點疲憊,那我們不如這個周末就休息下吧,來做幾道有意思的面試題好了,當是對前面學習的總結好了。

事情不順利不要緊,我們一步一步來,沒有什么事情做不完的。

布局類

讓我們一起來做一個頁面

首先,我們需要一個布局。

請使用CSS控制3個div,實現如下圖的布局。

我們前面已經學了很多CSS方面的東西了,我們現在來看看這道題,我們會怎么做呢?

這道題限制了只能使用三個div,並且我多float布局比較厭惡,所以第一步應該不會采用float,但是也必須考慮各個瀏覽器的兼容性,於是我第一份答案出來了:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4     <style type="text/css">
 5         body { margin: 0; }
 6         div { background-color: Gray; color: White; text-align: center; }
 7         .main { margin-left: 310px; height: 350px; }
 8         .sidebar1 { width: 300px; height: 200px; position: absolute; top: 0; }
 9         .sidebar2 { width: 300px; height: 140px; position: absolute; top: 210px;  }
10         
11     </style>
12 </head>
13 <body>
14     <div class="main">main
15     </div>
16     <div class="sidebar1">sidebar1
17     </div>
18     <div class="sidebar2">sidebar2
19     </div>
20 </body>
21 </html>

各位看到了,雖然我比較像用inline-block,但是實施起來時候發現有點困難,並且我這里想到了其它東西:

主要內容優先原則,不管是怎樣的布局,我的main內容皆應該放到最前面,優先加載,這也對后面將之改成響應式布局有好處。

這樣做還有一個好處便是,我們主要內容若是臨時要在左邊的話,改起來也必將方便,不要動到html結構。

好了,我們現在來看看有沒有其它方法,比如float:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4     <style type="text/css">
 5         body { margin: 0; }
 6         div { background-color: Gray; color: White; text-align: center; }
 7         .main { margin-left: 310px; height: 350px; }
 8         .sidebar1 { width: 300px; height: 200px; float: left; }
 9         .sidebar2 { width: 300px; height: 140px; float: left; clear: left; margin-top: 10px;  }
10         
11     </style>
12 </head>
13 <body>
14     <div class="main">main
15     </div>
16     <div class="sidebar1">sidebar1
17     </div>
18     <div class="sidebar2">sidebar2
19     </div>
20 </body>
21 </html>

有以下幾個問題:

① 因為我們主要區域在前,所以后面兩個浮動元素要改變位置才行,這與我們主要內容在前規則違背

② 若是此處主要內容要顯示在左邊的話,原來的CSS與HTML結構皆需改變

③ 瀏覽器兼容問題,原來的做法是沒有兼容問題的,這里使用float不久后IE6下又會莫名其妙的搞好多問題出來(IE3像素,清楚浮動)

所以就這塊布局來說,我是不會使用float布局的。

PS:哪位大哥有不同的意見請一定留言

第二部分:用javascript優化布局

由於我們的用戶群喜歡放大看頁面

於是我們給上一題的布局做一次優化。

當鼠標略過某個區塊的時候,該區塊會放大25%,

並且其他的區塊仍然固定不動。

於是我們來看看這道題第二個需求,他要鼠標划上擴大25%,根據我們布局1的話,這個題應該比較簡單,而且某些情況下也許鏈js都不必使用了,但是我們這里不管他:

PS:各位請不要小看這一塊,你認真做了的話,他會讓你感受到,沒jquery並且沒有形成自己庫的渺小,單單是設置樣式,設置class都會費盡很多

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         
 7         body { margin: 0; }
 8         div { background-color: Gray; color: White; text-align: center; }
 9         .main { margin-left: 310px; height: 350px; }
10         .sidebar1 { width: 300px; height: 200px; position: absolute; top: 0; }
11         .sidebar1:hover { background-color: Green; border: 1px solid black; z-index: 100; }
12         .sidebar2 { width: 300px; height: 140px; position: absolute; top: 210px;  }
13     </style>
14     <script type="text/javascript">
15         function preViewHtml(el) {
16             if (!el) return false;
17             var w = parseInt(el.offsetWidth);
18             var h = parseInt(el.offsetHeight);
19             setCss(el, 'width', w * 1.25 + 'px');
20             setCss(el, 'height', h * 1.25 + 'px');
21             setCss(el, 'background-color', parseInt(el.offsetHeight) * 1.25 + 'px');
22 
23             addEvent(el, 'mouseout', function () {
24                 setCss(el, 'width', '');
25                 setCss(el, 'height', '');
26             });
27             
28         }
29 
30         function addEvent(el, type, fn) {
31             if (el.attachEvent) {
32                 el['e' + type + fn] = fn;
33                 el[type + fn] = function () { obj['e' + type + fn](window.event); }
34                 el.attachEvent('on' + type, obj[type + fn]);
35             } else
36                 el.addEventListener(type, fn, false);
37         }
38         function removeEvent(el, type, fn) {
39             if (el.detachEvent) {
40                 el.detachEvent('on' + type, obj[type + fn]);
41                 el[type + fn] = null;
42             } else
43                 el.removeEventListener(type, fn, false);
44         }
45 
46         function addClass(el, k) {
47 
48         }
49 
50         function removeClass(el, k) {
51 
52         }
53 
54         function getCss(el, k) {
55             if (el) {
56                 if (el.style[k]) {
57                     return el.style[k];
58                 }
59                 return null;
60             }
61         }
62 
63         function setCss(el, k, v) {
64             if (el) {
65                 if (!el.style || el.style.length == 0) {
66                     el.style = {};
67                 }
68                 el.style[k] = v;
69             }
70         }
71     </script>
72 </head>
73 <body>
74     <div class="main">main
75     </div>
76     <div class="sidebar1" id="preView" onmouseover="preViewHtml(this)" >sidebar1
77     </div>
78     <div class="sidebar2">sidebar2
79     </div>
80 </body>
81 </html>
View Code

這個代碼有很多問題,其實我本意也不完全是這個意思啦,其實要做好這道題我覺得應該做好以下幾個事情:

① 封裝獲取dom的函數

② 封裝操作dom屬性的函數

③ 封裝操作class的函數

④ 封裝事件綁定的函數

有了以上幾塊后,這道題便很簡單了,所以我們這里還是來封裝以下吧。。。雖說我還真沒全部寫過,沒有jquery操作dom真討厭。。。

 1 function getById(id) {
 2 
 3 }
 4 
 5 function getAttr(el, k) {
 6 
 7 }
 8 
 9 function setAttr(el, k, v) {
10 
11 }
12 
13 function addClass(el, k) {
14 
15 }
16 
17 function removeClass(el, k, v) {
18 
19 }
20 
21 function getStyle(el, k) {
22 
23 }
24 
25 function setStyle(el, k, v) {
26 
27 }
28 
29 function addEvent(el, type, func) {
30 
31 }
32 
33 function removerEvent(el, type, func) {
34 
35 }

以下附上實現的代碼:

首先來幾個簡單的:

 1 function getById(id) {
 2     return id ? document.getElementById(id) : null;
 3 }
 4 
 5 function getAttr(el, k) {
 6     if (el) {
 7         return el.getAttribute[k];
 8     }
 9     return null;
10 }
11 
12 function setAttr(el, k, v) {
13     if (el) {
14         el.setAttribute(k, v);
15     }
16 }
17 
18 function addClass(el, k) {
19     if (el) {
20         var arr = el.className.split(' ');
21         var arrClass = [];
22         var isExist = false;
23         for (var i = 0, len = arr.length; i < len; i++) {
24             if (arr[i] != '') arrClass.push(arr[i]);
25             if (arr[i] == k) {
26                 isExist = true;
27                 break;
28             }
29         }
30         if (isExist == false) {
31             arrClass.push(k);
32             var cls = arrClass.join(' ');
33             el.className = cls;
34             setAttr(el, 'class', cls)
35         }
36     }
37 }
38 
39 function removeClass(el, k) {
40     if (el) {
41         var arr = el.className.split(' ');
42         var arrClass = [];
43         for (var i = 0, len = arr.length; i < len; i++) {
44             if (arr[i] != '' && arr[i] != k) arrClass.push(arr[i]);
45         }
46 
47         var cls = arrClass.join(' ');
48         el.className = cls;
49         setAttr(el, 'class', cls)
50     }
51 }

我們看到,firefox可以獲取class列表,而ie幾個瀏覽器只有className這一屬性,所以操作class時候我們要用到。

但是獲取當前樣式卻比較麻煩,還需要計算各個樣式表的比重,我們這里用不到就暫時忽略了。

以上簡單測試了一番,基本沒有問題,我最后加上事件綁定,便暫時告一段落。

 1 function addEvent(el, type, func) {
 2     if (el) {
 3         if (el.attachEvent) {
 4             el.attachEvent('on' + type, func);
 5         } else {
 6             el.addEventListener(type , func, false);
 7         }
 8     }
 9 }
10 
11 function removerEvent(el, type, func) {
12     if (el) {
13         if (el.attachEvent) {
14             el.detachEvent('on' + type, func);
15 
16         } else {
17             el.removeEventListener(type, func, false);
18         }
19     }
20 }

以上是很簡陋的做法,若是要完全解決兼容性方法,需要call篡改IE事件中this指向,以及傳入的e參數,但是那樣對刪除事件有提出了麻煩,我們這里便不管他了。

結語

今天狀態不佳,暫時這樣了吧,先去吃個飯再說。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM