Home  >  Article  >  Web Front-end  >  JS method to solve position:sticky compatibility problem

JS method to solve position:sticky compatibility problem

小云云
小云云Original
2018-01-15 10:35:133680browse

This article mainly introduces the JS method to solve the compatibility problem of position:sticky. It has certain reference value. Interested friends can refer to it. I hope it can help everyone.

The sticky layout is used in the project, but due to compatibility issues, it is not very compatible on the Android side, so in order to completely solve this problem, I can only write a component to solve this troublesome problem. Why is this here? There is a reason why it is a component rather than an instruction, which will be discussed below.

position: The compatibility and function of sticky

The compatibility of sticky displayed on Caniuse is as follows:

The function of Sticky is equivalent to a combination of relative and fixed. When the modified target node is on the screen, it appears as relative, and when it goes beyond the screen, it appears as fixed. Because of this feature, we can implement a sticky simulation effect.

sticky component implementation

template part


##

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

Code interpretation: Here I use the component The reason why it is implemented instead of using instructions is that although the instructions are non-invasive and more convenient to use, there is a drawback that when the modified node is fixed, it will break away from the document flow and change the height of the scroll bar. If It’s okay to just use it with the native scroll bar (of course, there will also be the problem of scrolling too fast), but because it’s working with custom scrolling, it’s implemented in this compromise way. The outermost layer is a sticky layer, which determines whether the browser supports sticky. If not, use relative instead, so that the height of the browser will not be changed, and then dynamically change the postion of the stick-warp layer to achieve the effect.

css part


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

Code interpretation: The background color setting of the warp layer here is consistent with sticky, so that the transition will not be too stiff, and the height and top are both It is implemented based on the user's customization of the outer sticky, so this part can be completed simply with css.

JS part


<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>

Code interpretation: Here we mainly use cssSupport to judge the browser support, and then use multiple custom scrolling y- Monitor the scroll event and monitor the change of top value to realize the conversion between fixed and absolute in the sticky-warp layer. The general idea and implementation process are as above. The github address for customized scrolling: https://github.com/yejiaming/scroll. The github address for the reference implementation of sticky components and instructions under native scrolling is as follows: https: //github.com/yejiaming/sticky


Related recommendations:


Detailed explanation of Sticky footer layout of CSS classic layout

How to use Sticky components to implement tab navigation and scroll navigation with sticky effects_javascript skills

A brief discussion on the improved implementation of Sticky components_javascript skills

The above is the detailed content of JS method to solve position:sticky compatibility problem. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn