五月開始出來找工做,簡歷被一家創業公司相中,就毫無準備的去面試了。面試過程天然也是慘不忍睹,但面試官給機會,就給出了一道題,完成相似於攜程用車預定頁面的時間選擇組件。離開時面試官提示:1、這個實際上是一個組件,只要改變組件綁定的數據,能實現不少選擇;2、只針對移動端作。本身拿着面試題,其實挺彷徨的,除了知道用本身最擅長的jQuery.fn來實現這個組件,其餘的一無所知,後面不斷查資料、搗騰,倒也作出來了,但最後和技術Leader深刻聊時,問及這個插件CSS部分的優化,本身答的確實不咋地,因此被無情的拒絕,後面本身閒下來,再看那個CSS時,寫的真的是狗貓兒不是,而後就再一次搗騰,學習到了不少。這裏作以記錄,以避免本身再次入坑。css
組件演示地址:https://closertb.github.io/De...html
組件用到的框架:jQuery.js,iScroll.js Scroll入門Demo:http://iscrolljs.com/git
關於實現:大概就是實例化三個iScroll,併爲每一個實例綁定的數據,若是數據間有父子關係,須要聯動,則可使用一個定時器(iScroll有相應的觸發事件,但當時沒時間仔細學,因此本身寫的定時器來實現,iScroll內部也是經過定時器實現的),來檢測父原件的值是否變化,從而改變子組件的綁定數據,看源碼比較好。github
滾動組件HTML主要代碼:web
<div id="ui-scroll"> <div id="grandwrapper"> <ul></ul> </div> <div id="parentwrapper"> <ul></ul> </div> <div id="childwrapper"> <ul></ul> </div> </div>
CSS代碼:面試
#ui-scroll{position: absolute;overflow: hidden;background: #F8F8F8;width:94%; margin:10px 3%;border: 1px solid #E0E0E0; border-radius: 4px;height:120px;text-align: center;line-height: 40px;top:50px;left:0;} #ui-scroll div{display:inline-block;height:100%; width:32%;margin-left:1%;text-align: center;vertical-align:top;} #ui-scroll li{color: #898989;font-size: 1.6rem;}
JS代碼:(這裏用到的是iScroll 4**版本5和4實例化參數設置不少不同)瀏覽器
grand = new iScroll("grandwrapper",{snap:"li",vScrollbar:false, onScrollEnd:function () { indexgrand= (this.y/40)*(-1)+(rows-1)/2; }}); //標準實例化參數 target =new iScroll("targetId",options)(iScroll 4) //標準實例化參數 target =new iScroll("#targetId",options)(iScroll 5) //粗略看,4和5好像差很少,都是傳入一個el和一個options,但傳入el時,區別在#號,也許你猜到了,4獲取Dom節點用的是getElementById(el),而5採用了querySelector(el) //options:設置snap:"li",用於自動捕獲目標點,vScrollbar設置爲false用來設置是縱向滾動條不顯示,onScrollEnd設置了一個事件監聽,每一次滑動結束後,獲取當前被選中的值的Index,40是CSS設置的line-height值,而(rows-1)/2是爲了插件能夠設置顯示行數,因此須要offset這個空值。
緣由:wrapper元素height設置不正確。(這也是本身給本身挖的最大的坑)
我的理解:iSroll實現滑動,其實就是在你的屏幕中,把你要滑動的區域實例化成屏幕中的屏幕,因此當你的內容不足以撐開你實例化的這塊屏幕時,固然就無法滑動。和在瀏覽器的滑動條同樣,當咱們web的內容高度尚未屏幕高度高時,瀏覽器的滑動條是不會出現的。
因此順着這個思路,本身查看了iScroll的相關源碼:app
if (dir == 'h') { //橫向滑動 that.hScrollbarSize = that.hScrollbarWrapper.clientWidth; that.hScrollbarIndicatorSize = m.max(mround(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8); that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px'; that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize; that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX; } else { //縱向滑動 that.vScrollbarSize = that.vScrollbarWrapper.clientHeight; //獲取元素高度 that.vScrollbarIndicatorSize = m.max(mround(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8); that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px'; that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize; that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY; }
而後又在devtools裏$("#grandwrapper").css("height")打印了本身寫的wrapper的高度920px,見鬼了,仔細一想920/40 =23,好像有點眉目了,本身寫CSS時,沒有限定其高度,因此高度爲auto,隨子元素個數變化而變化。因此立刻,立馬去CSS中設置了一個高度160px:其實該設置成120px,因此這又引出了另外一個問題:
縱向雖然能夠滑動選擇了,可是無法選擇最後一個元素,緣由,緣由就在於這個160px,實例化的滑動區域比可見區域高,因此滑動不能選擇最後一個元素。框架
緣由:當更新數據後,雖然實例化的wrapper區域是必定的,但滑動內容是針對wrapper的子元素,子元素個數變化,就會引發高度變化,因此每一次更新數據後,都應執行一次refresh()方法更新滑動內容高度,這樣才能保證每一個選項都能被選中。ide
#ui-scroll{position: absolute;overflow: hidden;height:120px;line-height: 40px;top:50px;} #ui-scroll div{position:absolute; width:32%;}
首先塊級元素,width默認爲100%,但inline-block則不是,默認爲auto
但塊級元素,height默認爲auto,而不是父級元素的100%。但若是這樣寫
#ui-scroll div{position:absolute; width:32%;top: 0;bottom: 0;}
div高度是和ui-scroll相關的,divHeight = ui-scrollHeight-top-bottom(但有個前提,ui-scroll元素定位不能是static)。因此這裏height設置等價於height:100%
最近面試,技術面基本都要問關於float的相關知識,以及怎麼解決。當時和技術Leader聊這個組件時,本身也是實在了float這個問題上,大概意思是若是不用inline-block,就用浮動你怎麼實現,本身叭叭叭說了一堆,後來想一想,真是蠢,根本就沒有get到題點。
關於浮動的定義,百度
怎麼清除浮動,從思路上來說,有兩種方式:
一、clear:both
方法有不少種:
A:在浮動元素後加空元素,<div "style:clear:both"></div>
B:僞元素 parent:after{}
二、BFC(塊級格式上下文)
關於塊級格式上下文的定義,推薦看這一篇:http://www.cnblogs.com/lhb25/...
其實就是經過設置一個屬性來觸發BFC,而後達到清除浮動的目的。
觸發BFC方式:
一、根元素
二、float屬性不爲none
三、position爲absolute或fixed
四、display爲inline-block, table-cell, table-caption, flex, inline-flex
五、overflow不爲visible