這兩天接了一個需求,頁面是這樣的
然后需求是頁面中的這個表格當頁面向上滾動,且表格的表頭到達窗口上方時,表頭懸浮在頁面的上方,表格正常滾動,這樣表格內的數據可以隨時看到表頭內容。
一開始我認為這是極簡單的,就當頁面滾動,判斷表頭到窗口的距離,當=0的時候觸發事件然后讓表頭position:fixed不就萬事大吉了嗎?於是我對漂亮又萌萌噠的產品妹子說,放心吧,這個簡單的很一會就能完事,當時我的表情是這樣的
但是當我開始寫(首先你要知道,我是個js小白,表問我為什么。。。),問題就來了。首先,這個頁面滾動應該用$(window).scroll,那么我怎么去判斷表頭到窗口的距離呢?我立馬想到了offset,這里正好溫習一下offset()和position()的區別,首先呢他們確實都代表位置,不過呢 ,offset().top是元素到文檔頂部的距離,意思就是這個值呢如果你沒操作dom正常來說,是不會發生變化滴,position是元素相對於父元素的距離就更別想了。。。沒有一個對勁。。。然后我又想到了scrollTop(),你看這個跟scroll長得那么像肯定沒問題!不過等我仔細看了一下API就傻了,"獲取匹配的元素集合中第一個元素的當前垂直滾動條的位置或設置每個匹配元素的垂直滾動條位置",讀了一遍沒讀明白,但是我理解的是元素在該區域內的滾動條的滾動距離,比如說你寫了一個div,高度固定,然后overflow:scroll,那么該div的scrollTop就是這個內容超出后出現的滾動條的垂直距離,說了一堆感覺好像也沒啥用。。。。總之就是不能單純用scrollTop()來獲取這個表頭到窗口頂部的距離了。
一時間陷入了僵局。。。怎么辦呢,我去廁所思考人生了。。。
嗯,經過在馬桶上的思想斗爭,我的思路無比開朗。既然單個不行就組合吧,使用$('body').scrollTop()與表頭的offset().top差值,因為頁面打開默認滾動條是在頂部的,如果要將表頭滾到窗口的頂部那么,滾動條就要滾動表頭的offset().top的距離,當大於這個值那么表頭肯定就已經在頂部的負值區域看不到了,嗯。。。
解決了這個問題之后,我為自己歡欣鼓舞,然而,還有一個問題在等着我。那就是表頭直接position:fixed的話,實際上此時表頭已經脫離了正常的文檔流。除了里面的內容樣式都已經沒了啊,我摔!就算勉強加上了樣式,因為表格的內容是自由擴展的,所以每一列的列寬是由表頭和表內的元素共同決定的,單獨把表頭拿出來是不行不行滴啊!!
然后,嗯,我動態生成了一個div,clone了整個表,獲取表頭的高給這個div,然后讓這個div overflow:hidden了!天阿魯,我簡直就是個天才。不再廢話了,獻上源碼~
<script src="js/jquery-latest.js"></script>
<script> $(function(){ var scroll_bar = $("#scroll_bar");//表格的id var bar_head = $("#bar_head");//表頭 var bar_height = bar_head.height();//表頭高 var sroll_header= scroll_bar.clone().attr('id','bb');//更改復制的表格id $(window).scroll(function(){ var scroll_top = $('body').scrollTop() - scroll_bar.offset().top;//判斷是否到達窗口頂部 if (scroll_top > 0) { $('body').append('<div id="shelter"></div>');//復制的表格所在的容器 $("#shelter").css({'height':bar_height,'position':'fixed','top':'0','overflow':'hidden','width':'1200px','margin': '0 auto','left':'0','right':'0','border-bottom':'1px solid #c8c8c8'}); sroll_header.appendTo('#shelter'); $('#shelter table').removeClass(); //刪除table原來有的默認class,防止margin,padding等值影響樣式 $('#shelter table').css({'width':'100%','background-color':'#f0f0f0'}); $('#shelter table tr th').css({'height': bar_height,'width':'140px','border':'1px solid #c8c8c8'});//此處可以自行發揮 $('#shelter table tr td').css({'padding':'10px','text-align':'center'}); $('#shelter').show(); }else { $('#shelter').hide(); } }); }); </script>
另外附上一個我找的其他實現方法,但是我覺得太重,所以放棄了,還是把鏈接放下大家自己參考吧
http://www.uedsc.com/sticky-table-headers-columns.html
就這么多吧,歡迎各位童鞋批評質疑~
因為到現在我還是不知道怎么上傳這個代碼的壓縮包,所以我就直接把完整的一個demo代碼放這邊吧,這個代碼依賴jQuery,我的版本是1.8.3,
不過我的方法里面好像沒有涉及到版本更新會引起沖突的內容,所以應該對jQuery的版本要求不高。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表格頂部懸浮效果</title> <script src="jquery-latest.js"></script> <style> .container { width: 980px; margin: 0 auto; } .top { height: 100px; background-color: #80ff80; } .table { margin-top: 50px; background-color: #f0f0f0; } .table thead { height: 50px; } .table tr td, .table tr th { padding: 20px; text-align: center; } </style> </head> <body> <div class="top"></div> <table id="scroll_bar" class="table container" border="1"> <thead> <tr id="bar_head"> <th>表頭1</th> <th>表頭2</th> <th>表頭3</th> <th>表頭4</th> <th>表頭5</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>5</td> <td>3</td> <td>4</td> </tr> </tbody> </table> <script> $(function(){ var scroll_bar = $("#scroll_bar");//表格的id var bar_head = $("#bar_head");//表頭 var bar_height = bar_head.height();//表頭高 var sroll_header= scroll_bar.clone().attr('id','bb');//更改復制的表格id $(window).scroll(function(){ var scroll_top = $('body').scrollTop() - scroll_bar.offset().top;//判斷是否到達窗口頂部 if (scroll_top > 0) { $('body').append('<div id="shelter"></div>');//復制的表格所在的容器 $("#shelter").css({'height':bar_height,'position':'fixed','top':'0','overflow':'hidden','width':'980px','margin': '0 auto','left':'0','right':'0','border-bottom':'1px solid #c8c8c8'}); sroll_header.appendTo('#shelter'); $('#shelter table').removeClass(); //刪除table原來有的默認class,防止margin,padding等值影響樣式 $('#shelter table').css({'width':'980px','background-color':'#f0f0f0','margin':'0 auto'}); $('#shelter table tr th').css('height', bar_height);//此處可以自行發揮 $('#shelter table tr td').css({'padding':'20px','text-align':'center'}); $('#shelter').show(); }else { $('#shelter').hide(); } }); }); </script> </body> </html>
