一道面試題帶來的前端優化——實現星星點評

範大腳腳發表於2017-12-07
前言
人人都會失業,這不巧小的這裡就準備失業了,團隊解散不是病,突然解散要人命。
我們工作中面對這種突然團隊解散的問題,對職業生涯規劃是有很大問題的,他可以讓你一夜回到革命前:
比如我幾年的工齡(<=1)沒了;比如我今年年底年終獎又只有半年的了,比如我在這裡努力的結果付諸東流了……
說來說去,就一個結果,小的需要找工作了。於是那天就把簡歷掛了出來,也恰好有個招聘,就過去了,應該說毫無感覺,帶著及其失落的感情過去了……
面試過程中的題基本全知道,不管有印象的沒印象的,反正全知道……但是知道不等於瞭解,瞭解不等於深入!這裡又要為自己平時的不積累埋單了。
根據那次面試,我這裡有兩個總結點,最近會形成研究:javascript中的this;javascript中的冒泡機制
其實關於這兩個東西,我其實早有興趣研究,也早該研究,省略一萬字……反正最後沒有研究。
說回主題、說回正題
面試過程中,提出的一道題比較有意思,完了我一直想試試,這裡提出來大家研究:
這是在噹噹上截的圖,我要完成的功能就是這個。
滑鼠滑動到某個星上就將幾個高亮顯示。
最簡單與最戳相差不遠
碰到這類題,我一般使用神器jquery,但是我們做前端開發的,若是沒有一定涵養,第一次的方法必定是最容易實現的,往往也是最戳的:
話不多說,先上程式碼:
滑鼠劃上選中
功能一滑鼠劃上變顯示選中
思路:給每個li新增事件,改變其class影響背景變化:
於是乎我們完成了功能的第一步,現在我們要將滑鼠劃上的前面幾個都給選中,這不好辦呢。。。於是退一步又都加上id吧!
用到的圖片:
醜陋的完成功能
這個醜陋的程式碼,已經慘不忍賭,實現的效果尤使讓我不想看:
1 使用ul標籤,其html的結構可縮減
2 為每個li繫結事件,劃上幾次事件,離開幾次事件。。。。
3 多出了很多id……
4 顯示效果也沒有做優化,用的qq截圖,有點晃動
但是戳的程式碼也有他的優化的方法:
複製程式碼
 1 $(`#comment_star`).delegate(`li`, `mouseenter`, function (e) {
 2     var el = $(this);
 3     var num = el.attr(`star`);
 4     for (var i = 1; i <= parseInt(num); i++) {
 5         $(`#s` + i).addClass(`star_selcted`);
 6     }
 7 }).delegate(`li`, `mouseleave`,function (e) {
 8     var el = $(this);
 9     var num = el.attr(`star`);
10     for (var i = 1; i <= parseInt(num); i++) {
11         $(`#s` + i).removeClass(`star_selcted`);
12     }
13 });
複製程式碼
說是簡單優化,其實也沒什麼說的,無非是把事件繫結到了ul上,所需操作依舊很多。
如何優化?
對該題優化的主旨為:
零請求、無流量
減少dom操作
零請求無流量來說,這裡做的很好了,但是dom操作來說,怎一坑爹可言,其實我最開始想到的方法之所以在我看來不好優化,
因為他從開始就錯了,有了一個錯誤的開始,一個錯誤的基礎,要怎麼優化都是徒勞,所以我們改變思路,改變dom結構
改變背景圖片:demo.gif,小生還是用ps搞的呢,居然還是有點不像。。。
改變dom結構:
我的思路是使用兩個div處理,因為是邊寫邊發,所以我也不知道行不行得通,我們首先來看看使用一個div平鋪會怎樣?
複製程式碼
 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         body { background: #dfdfdf; }
 7         .star { background: url(“demo.gif”) repeat 0 0; width: 150px; height: 26px; }
 8         #star { }
 9         #s_star { background-position: 0 -30px;  }
10     </style>
11     <script src=”http://www.cnblogs.com/jquery-1.7.1.js” type=”text/javascript”></script>
12     <script type=”text/javascript”>
13         $(document).ready(function () {
14  
15         });
16     </script>
17 </head>
18 <body>
19     <div id=”star” class=”star”>
20     </div>
21     <div id=”s_star” class=”star”>
22     </div>
23 </body>
24 </html>
複製程式碼
形成了一下圖形
 
現在我們來做一件壞事,看看可不可以將兩個div重合:
1 body { background: #dfdfdf; }
2 .star { position: relative;}
3 .star div { background: url(“demo.gif”) repeat 0 0; width: 150px; height: 26px; }
4 #s_star { background-position: 0 -30px; position: absolute; left: 0; top: 0; }
若是改變其中一個寬頻的話……
 
於是我感覺我好像離我要的效果近了。於是我加了一點程式碼,設定個斷點來看看:
複製程式碼
$(document).ready(function () {
    $(`.star`).mouseenter(function (e) {
                
        var s = “;
    }).mouseleave(function (e) {
    });
});
複製程式碼
 
我在想這裡兩個屬性是否對我有用?我是否可以根據他們設定div的寬度呢?
 
複製程式碼
 1 $(document).ready(function () {
 2     $(`.star`).mouseenter(function (e) {
 3         var el = $(this);
 4         var x = e.clientX;
 5         var left = el.offset().left;
 6         var w = x – left
 7 
 8         var s = “;
 9     }).mouseleave(function (e) {
10 
11     });
12 });
複製程式碼
我這樣的話是不是獲得滑鼠相對於元素座標的位置了呢?然後根據該屬性設定絕對定位元素寬度試試:
即將成功的程式碼
 我們看到我滑鼠指哪裡,絕對定位寬度就到哪裡,於是我們離勝利就只差一步了!!!判斷寬度:
複製程式碼
 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         body { background: #dfdfdf; }
 7         .star { position: relative; width: 150px;}
 8         .star div { background: url(“demo.gif”) repeat 0 0; width: 150px; height: 26px; }
 9         #s_star { background-position: 0 -30px; position: absolute; left: 0; top: 0; width: 0; }
10         
11     </style>
12     <script src=”http://www.cnblogs.com/jquery-1.7.1.js” type=”text/javascript”></script>
13     <script type=”text/javascript”>
14         $(document).ready(function () {
15             $(`.star`).mousemove(function (e) {
16                 var el = $(this);
17                 var x = e.clientX;
18                 var left = el.offset().left;
19                 var w = x – left;
20                 var tmp = w % 30 – 30;
21                 w = w – tmp;
22                 $(`#s_star`).css(`width`, w + `px`);
23                 var s = “;
24             }).mouseleave(function (e) {
25                 $(`#s_star`).css(`width`, `0px`);
26             });
27         });
28     </script>
29 </head>
30 <body>
31     <div class=”star”>
32         <div id=”star”>
33         </div>
34         <div id=”s_star”>
35         </div>
36     </div>
37 </body>
38 </html>
複製程式碼
現在我們就發現,他完全按照我的套路出牌了啦!!!優化結束!!!
這樣的程式碼我就可以結束了,我感覺基本達到我的要求了!
噹噹的做法
 閉門造車結束,我們來看看噹噹是怎麼做的呢?
我們先截個圖看看,我大概知道是什麼回事了,於是我們來模擬一番:
噹噹的背景圖:
我們發現他是一張整圖,然後我也試試實現以下程式碼:
複製程式碼
 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         body { background: #dfdfdf; }
 7         #star { background: url(“dang.jpg”) repeat 0 0; width: 335px; height: 26px; }
 8     </style>
 9     <script src=”http://www.cnblogs.com/jquery-1.7.1.js” type=”text/javascript”></script>
10     <script type=”text/javascript”>
11         $(document).ready(function () {
12            
13         });
14     </script>
15 </head>
16 <body>
17     <div id=”star”>
18     </div>
19 </body>
20 </html>
複製程式碼
毫無修飾的情況下是這個樣子,那麼我們來簡單調整下下:
 #star { background: url(“dang.jpg”) repeat -140px 0; width: 135px; height: 26px; }
於是基本還原,現在來加上樣式控制,噹噹寫了幾個css,我這裡就東施效顰一番,直接不寫css了:
看我實現的程式碼
你看著,他會跟著滑鼠走動,那麼我們功能就已經實現一半了。
複製程式碼
 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         body { background: #dfdfdf;  }
 7         #star { background: url(“dang.jpg”) no-repeat -140px 0; width: 140px; height: 26px; }
 8     </style>
 9     <script src=”http://www.cnblogs.com/jquery-1.7.1.js” type=”text/javascript”></script>
10     <script type=”text/javascript”>
11         $(document).ready(function () {
12             $(`#star`).mousemove(function (e) {
13                 var el = $(this);
14                 var x = e.clientX;
15                 var left = el.offset().left;
16                 var w = x – left;
17                 w = -140 + w;
18                 if (w < 0) w = -1 * w;
19                 w = parseInt(w / 28) * 28;
20                 el.css(`background-position`, `-` + w + `px 0`);
21                 var s = “;
22             }).mouseleave(function (e) {
23                 var el = $(this);
24                 el.css(`background-position`, `-140px 0`);
25             });
26         });
27     </script>
28 </head>
29 <body>
30     <div id=”star”>
31     </div>
32 </body>
33 </html>
複製程式碼
於是我可恥的認為自己實現了當當的功能了。。。。。
至於噹噹實現的方法,和我實現的方法,各位同學可以研究下,我可恥的認為估計噹噹的好吧。。。。
結語
有時候我在想我的js功底如何才能進步,如何才能成為高手,閱讀jquery原始碼雖說是一個方式,當更應該平時多思考多動手的說,
看看各大網站實現方案,與自己所想的實現方案,就可以看到差距了。
而且我們平時面試的時候也不要小看那些面試題,其實他都是有針對性的,可以歸納為一個知識點做研究,
我認為這也是一個進步的方向,最後期待各位拿出自己的解決方案喲。
 如果你覺得這篇文章還不錯,請幫忙點選一下推薦,謝謝!
本文轉自葉小釵部落格園部落格,原文連結:http://www.cnblogs.com/yexiaochai/archive/2013/04/21/3033910.html,如需轉載請自行聯絡原作者


相關文章