使用Sticky組件實現帶sticky效果的tab導航和滾動導航的方法,stickytab

來源:互聯網
上載者:User

使用Sticky組件實現帶sticky效果的tab導航和滾動導航的方法,stickytab

sticky組件,通常應用於導航條或者工具列,當網頁在某一地區滾動的時候,將導航條或工具列這類元素固定在頁面頂部或底部,方便使用者快速進行這類元素提供的操作。

在這篇文章Sticky組件的改進實現提供了一個改進版的sticky組件,並將示範效果應用到了自己的部落格。有了類似sticky的這種簡單組件,我們就可以在利用它開發更豐富的效果,比如本文要介紹的tab導航和滾動導航。實現簡單,示範效果如下:

tab導航(對應tab-sticky.html):

滾動導航(對應nav-scroll-sticky.html):

1. tab導航的實現

tab導航的需求是:在點擊導航項的時候,除了切換tab內容,還要控制滾動,將要顯示的tab內容置頂,並且要剛好顯示在sticky元素的下邊。由於demo是用bootstrap做的,bootstrap提供的tab組件非常簡單好用,我們可以在tab組件提供的shown.bs.tab的事件回調裡做滾動控制處理,所以這個效果實現起來比較容易:

<script>var $target = $('#target');new Sticky('#sticky', {unStickyDistance: 60,target: $target,wait: 1,isFixedWidth: false,getStickyWidth: function($elem) {return $elem.parent()[0].offsetWidth;}});$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {window.scrollTo(0, $target[0].getBoundingClientRect().top + getPageScrollTop() + 1);});function getPageScrollTop() {return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;}</script>

html結構:


2. 滾動導航實現

滾動導航相對麻煩一些,tab組件裡面,只會顯示與當前啟用的tab項對應的tab內容,而滾動導航裡面,要導航的所有內容都是已經在頁面中渲染完畢的,它的需求是:

1)點擊導航項的時候,控制頁面滾動,自動將與點擊的導航項對應的內容置頂顯示,並且要剛好顯示在sticky元素的下邊;

2)頁面滾動的時候,根據當前顯示的導航內容自動給相應的導航項添加active樣式。

儘管聽起來複雜,但是demo中的實現還是比較容易:

<script>var $sticky = $('#sticky');var $target = $('#target');new Sticky($sticky, {unStickyDistance: 60,target: $target,wait: 1,isFixedWidth: false,getStickyWidth: function ($elem) {return $elem.parent()[0].offsetWidth;}});var offsetTop = 60;//實現點擊tab項自動滾動到導航內容的效果$sticky.on('click', 'a', function (e) {e.preventDefault();var $this = $(e.currentTarget);var $parent = $this.parent();if($parent.hasClass('active')) return;$sticky.find('li.active').removeClass('active');$parent.addClass('active');var target = $this.data('target') || $this.attr('href');var $target = $(target);window.scrollTo(0, Math.floor($target[0].getBoundingClientRect().top) + getPageScrollTop() - offsetTop);});/*** Math.floor是解決rect.top或rect.bottom帶小數問題*///實現滾動時根據當前顯示的導航內容自動給相應的導航項添加active樣式$(window).scroll(throttle(function(){var $curItem = $sticky.find('a').filter('[href=' + getCurTarget() + ']');var $parent = $curItem.parent();if($parent.hasClass('active')) return;//最後的blur是為了去掉:active及:focus偽類的樣式$sticky.find('li.active').removeClass('active').find('a').trigger('blur');$parent.addClass('active');},1));//擷取當前顯示的導航內容元素的idfunction getCurTarget() {for(var targets = ['#First', '#Second', '#Third'], i = 0, l = targets.length; i < l; i++) {var curRect = $(targets[i])[0].getBoundingClientRect();if(Math.floor(curRect.top) <= offsetTop && Math.floor(curRect.bottom) > offsetTop) {return targets[i];}}return targets[0];}function getPageScrollTop() {return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;}//這個函數在實際工作中是應該抽出來的,否則sticky.js裡面還有一份重複的function throttle(func, wait) {var timer = null;return function () {var self = this, args = arguments;if (timer) clearTimeout(timer);timer = setTimeout(function () {return typeof func === 'function' && func.apply(self, args);}, wait);}}</script>

html結構:


3. 總結

本文結合sticky組件,提供了2種導航效果實現,相容IE9+,firefox以及chrome,感興趣可以下載源碼再去詳細瞭解。在實現tab導航的時候,因為有bs的tab組件所以實現起來非常容易,也沒有必要把sticky跟tab組件再封裝起來形成一個新組件,畢竟效果的實現代碼已經比較簡單了。在實現滾動導航的時候,因為沒有用tab組件,所以滾動導航的那兩個需求點都是單獨實現的,在實際情況中,這兩個功能可以封裝成2個獨立的組件或者1個組件,這樣就能把實現代碼寫的像tab導航那樣簡單,不過本文沒有再深入去介紹這兩個組件的寫法,因為這不是本文主要想介紹的內容,雖然我很想這麼做,後續肯定會再寫部落格來介紹這兩個組件,簡單的東西不造一下輪子,簡直是浪費機會。在實現這兩個效果的時候,也有2點收穫:

1)firefox以及IE,先讓網頁,然後再重新整理,雖然網頁還會顯示在重新整理的位置,但是不會觸發scroll事件,所以今後做scroll相關的組件,一定在組件初始化的時候主動掉一次scroll相關的回調;

2)getBoundingClientRect返回的rect對象相關的值,在IE和firefox下,都可能是小數,比如60.2222299999,這樣的數,在進行判斷的時候可能會跟預期情況不符,導致一些意外的BUG,如果不是特別嚴謹的話,可以用Math.floor對這些值進行取整,然後再用來計算或者判斷。比如滾動導航實現中,rect.top的值60.2222299999,offsetTop的值是60,期望是curRect.top <= offsetTop這個條件能夠成立,因為小數的原因,所以它不成立。

您可能感興趣的文章:
  • Firefox getBoxObjectFor getBoundingClientRect聯絡
  • 各種常用瀏覽器getBoundingClientRect的解析
  • javascript getBoundingClientRect() 來擷取頁面元素的位置的代碼[修正版]
  • javascript 擷取元素位置的快速方法 getBoundingClientRect()
  • js getBoundingClientRect() 來擷取頁面元素的位置
  • 擷取元素距離瀏覽器周邊的位置的方法getBoundingClientRect
  • 淺談Sticky組件的改進實現
  • 使用getBoundingClientRect方法實現簡潔的sticky組件的方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.