首頁  >  文章  >  web前端  >  JS解決position:sticky相容性問題的方法

JS解決position:sticky相容性問題的方法

小云云
小云云原創
2018-01-15 10:35:133751瀏覽

本文主要介紹了JS解決position:sticky的兼容性問題的方法,具有一定的參考價值,有興趣的小伙伴們可以參考一下,希望能幫助到大家。

在專案中有用到sticky的佈局,可是由於相容性問題,在安卓端沒有很好的相容,所以為了徹底解決這個問題只能寫一個元件來解決這個麻煩的問題,這裡為什麼是元件而不是指令是因為,是有原因的,下面會講到。

position:sticky的兼容性以及作用

Caniuse上顯示sticky的兼容性如下:

Sticky的作用相當於relative和fixed的結合體,當修飾的目標節點再螢幕中時表現為relative,當要超出的時候是fixed的形式展現,因為這個特性,我們就可以來實現一個sticky的模擬效果。

sticky元件實作

template部分


<template>
  <p class="sticky" :style="getPosition">
    <p class="sticky-warp">
      <slot></slot>
    </p>
  </p>
</template>

程式碼解讀:這裡我使用了元件來實現,而不用指令來實現的原因是:指令雖然是無侵入性的,更方便使用,可是有一個弊端就是當修飾的節點fixed的時候會脫離文檔流,會改變滾動的條的高度,如果僅僅是配合原生滾動條來實現是沒問題的(當然這也會存在滾動過快的問題),可是由於是配合自定義滾動所以,採取這種折中的方式來實現。最外層是sticky層,判斷瀏覽器是否支援sticky,不支援就使用relative來代替,這樣也就不會改變瀏覽器高度的情況了,然後動態改變stick-warp層的postion來實現效果。

css部分


<style scoped lang="less" rel="stylesheet/less">
  .sticky {
    width: 100%;
    .sticky-warp {
      width: 100%;
      background: inherit;
      will-change: change;
      height: inherit;
      top: inherit;
    }
  }
</style>

程式碼解讀:這裡的warp層的背景色設定和sticky一致,這樣過渡不會太生硬,高度和top都根據使用者對外層sticky的自訂來實現,這樣這部分簡單用css就可以完成了。

JS部分


<script type="text/babel">
  export default {
    data () {
      return {}
    },
    computed: {
      getPosition(){
        var position = this.cssSupport(&#39;position&#39;, &#39;sticky&#39;) ? &#39;sticky&#39; : &#39;relative&#39;;
        return &#39;position:&#39; + position;
      }
    },
    props: {},
    beforeMount () {
    },
    mounted(){
      this.init();
    },
    deactivated(){
      if(this.cssSupport(&#39;position&#39;, &#39;sticky&#39;)) {
        return;
      }
      /*复位*/
      var elWarp = this.$el.querySelector(&#39;.sticky-warp&#39;);
      elWarp.position = &#39;absolute&#39;;
    },
    methods: {
      init(){
        if (this.cssSupport(&#39;position&#39;, &#39;sticky&#39;)) {
          return;
        }
        var el = this.$el, target = this.$el.parentNode,
            elWarp = this.$el.querySelector(&#39;.sticky-warp&#39;),
            top = this.getNumberValue(document.defaultView.getComputedStyle(el).top);
        this.addScrollListen(target, (event)=> {
          if (el.getBoundingClientRect().top <= top) {
            elWarp.style.position = &#39;fixed&#39;;
          }
          if (el.getBoundingClientRect().top >= 0 && elWarp.style.position != &#39;absolute&#39;) {
            elWarp.style.position = &#39;absolute&#39;;
          }
        })
      },
      cssSupport: function (attr, value) {
        var element = document.createElement(&#39;p&#39;);
        if (attr in element.style) {
          element.style[attr] = value;
          return element.style[attr] === value;
        } else {
          return false;
        }
      },
      getNumberValue(pxValue){
        var value = String(pxValue).match(/^\-?\+?[0-9]+/g);
        return value ? Number(value) : undefined;
      },
      addScrollListen(target, cb){
        target.addEventListener(&#39;y-scroll&#39;, (event)=> {
          cb && cb(event);
        });
      }
    },
  }

 
</script>

程式碼解讀:這裡面主要先用cssSupport來判斷瀏覽器的支援情況,然後透過多自訂滾動y- scroll事件的監聽,監聽top值的改變來實現sticky-warp層的fixed和absolute的轉換。大概原理的思路及實現過程就是上面這樣,對於自定義的滾動的github地址:https://github.com/yejiaming/scroll,sticky組件以及原生滾動下的指令參考的實現的github地址如下:https: //github.com/yejiaming/sticky

相關推薦:

CSS經典佈局之Sticky footer佈局詳解

#使用Sticky元件實現帶有sticky效果的tab導航和滾動導航的方法_javascript技巧

#淺談Sticky組件的改進實作_javascript技巧

以上是JS解決position:sticky相容性問題的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn