JS解决position:sticky的兼容性问题的方法


Posted in Javascript onOctober 17, 2017

在项目中有用到sticky的布局,可是由于兼容性问题,在安卓端没有很好的兼容,所以为了彻底解决这个问题只能写一个组件来解决这个麻烦的问题,这里为什么是组件而不是指令是因为,是有原因的,下面会讲到。

position:sticky的兼容性以及作用

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

JS解决position:sticky的兼容性问题的方法

Sticky的作用相当于relative和fixed的结合体,当修饰的目标节点再屏幕中时表现为relative,当要超出的时候是fixed的形式展现,因为这个特性,我们就可以来实现一个sticky的模拟效果。

sticky组件实现

template部分

<template>
  <div class="sticky" :style="getPosition">
    <div class="sticky-warp">
      <slot></slot>
    </div>
  </div>
</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('position', 'sticky') ? 'sticky' : 'relative';
        return 'position:' + position;
      }
    },
    props: {},
    beforeMount () {
    },
    mounted(){
      this.init();
    },
    deactivated(){
      if(this.cssSupport('position', 'sticky')) {
        return;
      }
      /*复位*/
      var elWarp = this.$el.querySelector('.sticky-warp');
      elWarp.position = 'absolute';
    },
    methods: {
      init(){
        if (this.cssSupport('position', 'sticky')) {
          return;
        }
        var el = this.$el, target = this.$el.parentNode,
            elWarp = this.$el.querySelector('.sticky-warp'),
            top = this.getNumberValue(document.defaultView.getComputedStyle(el).top);
        this.addScrollListen(target, (event)=> {
          if (el.getBoundingClientRect().top <= top) {
            elWarp.style.position = 'fixed';
          }
          if (el.getBoundingClientRect().top >= 0 && elWarp.style.position != 'absolute') {
            elWarp.style.position = 'absolute';
          }
        })
      },
      cssSupport: function (attr, value) {
        var element = document.createElement('div');
        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('y-scroll', (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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS遮罩层效果 兼容ie firefox jQuery遮罩层
Jul 26 Javascript
javascript类型转换示例
Apr 29 Javascript
node.js中的事件处理机制详解
Nov 26 Javascript
深入理解javascript中concat方法
Dec 12 Javascript
JS动态遍历json中所有键值对的方法(不知道属性名的情况)
Dec 28 Javascript
js+canvas实现动态吃豆人效果
Mar 22 Javascript
js处理包含中文的字符串实例
Oct 11 Javascript
vue计算属性及使用详解
Apr 02 Javascript
vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用
Apr 13 Javascript
Angular使用Restful的增删改
Dec 28 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
Feb 18 jQuery
vue中实现拖动调整左右两侧div的宽度的示例代码
Jul 22 Javascript
JS实现div模块的截图并下载功能
Oct 17 #Javascript
bootstrap模态框嵌套、tabindex属性、去除阴影的示例代码
Oct 17 #Javascript
AngularJS 控制器 controller的详解
Oct 17 #Javascript
VUE前端cookie简单操作
Oct 17 #Javascript
javascript 判断用户有没有操作页面
Oct 17 #Javascript
vue-router 路由基础的详解
Oct 17 #Javascript
如何抽象一个Vue公共组件
Oct 17 #Javascript
You might like
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)
2013/06/29 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
2015/02/08 PHP
PHP编程求最大公约数与最小公倍数的方法示例
2017/05/29 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
(function(){})()的用法与优点
2007/03/11 Javascript
使用正则替换变量
2007/05/05 Javascript
OfflineSave离线保存代码再次发布使用说明
2007/05/23 Javascript
javascript 函数式编程
2007/08/16 Javascript
javascript &amp;&amp;和||运算法的另类使用技巧
2009/11/28 Javascript
百度地图api应用标注地理位置信息(js版)
2013/02/01 Javascript
javascript获取xml节点的最大值(实现代码)
2013/12/11 Javascript
js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)
2013/12/11 Javascript
jQuery实现下拉框左右选择的简单实例
2014/02/22 Javascript
JavaScript实现数字数组按照倒序排列的方法
2015/04/06 Javascript
浅谈JavaScript中指针和地址
2015/07/26 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
2015/12/03 Javascript
javascript中arguments,callee,caller详解
2016/03/16 Javascript
再谈Javascript中的异步以及如何异步
2016/08/19 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
jQuery File Upload文件上传插件使用详解
2016/12/06 Javascript
详解javascript表单的Ajax提交插件的使用
2016/12/29 Javascript
js原生代码实现轮播图的实例讲解
2017/07/28 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
基于vue中keep-alive缓存问题的解决方法
2018/09/21 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
[01:29:31]VP VS VG Supermajor小组赛胜者组第二轮 BO3第一场 6.2
2018/06/03 DOTA
Python脚本按照当前日期创建多级目录
2019/03/01 Python
详解Python3迁移接口变化采坑记
2019/10/11 Python
Python版中国省市经纬度
2020/02/11 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
Python可以实现栈的结构吗
2020/05/27 Python
优衣库澳大利亚官网:UNIQLO澳大利亚
2017/01/18 全球购物
七一晚会主持词
2015/06/29 职场文书
2015年中学体育教师工作总结
2015/10/23 职场文书
党风廉政建设心得体会(2016最新版)
2016/01/22 职场文书