先上個圖:
布局很簡單,左右超過屏幕的部分自行滾動。
1. html
<div class="ce-container"> <div class="ce-leftBox"> //左邊的內容 </div> <div class="ce-rightBox"> //右邊的內容 </div> </div>
2.css
.ce-container { background: white; width: 100%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; padding-top: 50px; } .ce-container .ce-leftBox { float: left; width: 90px; height: 100%; border-right: 1px solid #F8F8F8; background: white; overflow-y: auto; text-align: center; } .ce-container .ce-rightBox { height: 100%; margin-left: 81px; overflow-y: auto; padding: 0 15px; }
說明重要點:
(1) container設置絕對定位top和bottom都要設置,再設置padding-top就能除開頭部返回欄鋪滿整個屏幕。
(2) 左右兩個盒子設置overflow-y:auto和高度100%,這樣就可以不用js來設置高度,讓div自行繼承高度,並且超過能滾動了。
(3)左邊盒子設置float,右邊的盒子設置margin-left就能達到左邊固定,右邊自適應寬度的效果。這利用了float的破壞性,脫離文檔流。
實現點擊左邊,右邊滾動的思路:
在左邊點擊列表的時候,獲取當前的索引值,然后,右邊再通過該索引值,獲取到對應部分的offset.top值,然后再設置右邊div scrollTop就可以了。但是!!!問題就這樣出現了。。。先來看看最初版的js
$('.ce-leftBox').on('click','.ce-leftItem',function(){ $(this).addClass('ce-lActive').siblings().removeClass('ce-lActive'); var idx=$(this).index(); var sTop=$('.ce-rightBox > .ce-rightItem').eq(idx).offset().top-50;//減50是去除頭部返回欄的高度 $('.ce-rightBox').stop(true).animate({"scrollTop":sTop},400); })
來看看初版效果:
a. 問題出現:
???為什么會錯亂???當沒有設置 $('.ce-rightBox').stop(true).animate({"scrollTop":sTop},400); 這條語句的時候,獲取到的sTop值是是正常的,但是加上這句話之后就出現了:點擊會計類,sTop是0;點擊工程類,sTop是321;點擊醫學類,sTop還是321???
b. 問題分析:
很明顯,就是這條語句影響了結果,那為什么呢?難道是div內部滾動之后,會影響子元素獲取offset.top的值?
果然,當第一次點擊工程類的時候,右邊div滾動了,這時候sTop的值是321,正常的,然后我再次點擊工程類的時候,按道理來講,sTop應該還是321,但是這時候,顯示的結果是0。為什么會出現這種情況呢?
c. 原因分析:
原來是這樣的
對於rightBox來說,它的頂部就是畫箭頭那點,那么當它滾動的時候,獲取子元素offset.top的值即獲取距離父級頂部的位置大小,就是獲取子元素距離rightBox頂部的距離,所以當第一次點擊工程類,右側滾動之后,再次點擊工程類,獲取到sTop的值是0。
那為什么是0呢?那是因為:overflow-y 屬性規定是否對內容的上/下邊緣進行裁剪 - 如果溢出元素內容區域的話。相當於滾動的那部分被裁剪了,所以相當於第一次滾動之后,工程類的頂部就是緊挨着父級的頂部的。所以第一次正確獲取,第二次已經滾動到rightBox頂部,再去獲取就是0了。
d. 解決方案:
既然滾動的那部分被裁減不能算作內容,那么我每次都去獲取滾動了多少,不就能正確獲取正常的sTop的值了嗎。最終版js
$('.ce-leftBox').on('click','.ce-leftItem',function(){ $(this).addClass('ce-lActive').siblings().removeClass('ce-lActive'); var idx=$(this).index(); var sTop=$('.ce-rightBox > .ce-rightItem').eq(idx).offset().top-50; var nowScrollTop=$('.ce-rightBox').scrollTop();//當前已經滾動了多少 $('.ce-rightBox').stop(true).animate({"scrollTop":sTop+nowScrollTop},400); })
最終效果圖:
這樣就正常了。。。
f. 擴展分析
那為什么其它需求需要整個window滾動的時候,每次獲取到的offset.top都是正常的呢???我估計整個頁面的滾動都不是overflow-y裁剪的那種滾動吧