div設置overflow-scroll滾動之后,jq獲取其子元素的offset.top出現問題。


先上個圖:

 布局很簡單,左右超過屏幕的部分自行滾動。

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設置絕對定位topbottom都要設置,再設置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裁剪的那種滾動吧

 


免責聲明!

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



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