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 相关文章推荐
jquery tablesorter.js 支持中文表格排序改进
Dec 09 Javascript
Ubuntu 11.10 安装Node.js的方法
Nov 30 Javascript
js实现翻页后保持checkbox选中状态的实现方法
Nov 03 Javascript
jQuery 属性选择器element[herf*='value']使用示例
Oct 20 Javascript
三种动态加载js的jquery实例代码另附去除js方法
Apr 30 Javascript
技术男用来对妹子表白的百度首页
Jul 23 Javascript
JavaScript中的异常捕捉介绍
Dec 31 Javascript
jquery滚动条插件slimScroll使用方法
Feb 09 Javascript
vue-resource 拦截器使用详解
Feb 21 Javascript
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
Jun 14 Javascript
Javascript执行流程细节原理解析
May 14 Javascript
微信小程序实现导航栏和内容上下联动功能代码
Jun 29 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
thinkPHP实现表单自动验证
2014/12/24 PHP
解析PHP之提取多维数组指定列的方法
2017/01/03 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
jQuery 事件队列调整方法
2009/09/18 Javascript
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
2010/06/12 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
2015/02/16 Javascript
bootstrap学习使用(导航条、下拉菜单、轮播、栅格布局等)
2016/12/01 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
vue 实现在函数中触发路由跳转的示例
2018/09/01 Javascript
微信小程序开发之路由切换页面重定向问题
2018/09/18 Javascript
vue组件传值的实现方式小结【三种方式】
2020/02/05 Javascript
微信小程序实现音频文件播放进度的实例代码
2020/03/02 Javascript
[00:57]辉夜杯战队访谈宣传片—VG
2015/12/25 DOTA
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python字符串特性及常用字符串方法的简单笔记
2016/01/04 Python
基于python log取对数详解
2018/06/08 Python
详解使用Python下载文件的几种方法
2019/10/13 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
pytorch 利用lstm做mnist手写数字识别分类的实例
2020/01/10 Python
python 实现PIL模块在图片画线写字
2020/05/16 Python
Python之字典添加元素的几种方法
2020/09/30 Python
pymongo insert_many 批量插入的实例
2020/12/05 Python
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
挪威手表购物网站:Klokker
2016/09/19 全球购物
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
怎样在程序里获得一个空指针
2015/01/24 面试题
英文自荐信
2013/12/15 职场文书
房地产开发计划书
2014/01/10 职场文书
工厂搬迁方案
2014/05/11 职场文书
讲文明知礼仪演讲稿
2014/09/13 职场文书
工程部文员岗位职责
2015/02/04 职场文书
全国爱牙日活动总结
2015/02/05 职场文书
民事撤诉申请书范本
2015/05/18 职场文书
2016年庆“七一”主题党日活动总结
2016/04/05 职场文书
2019公司管理制度
2019/04/19 职场文书
导游词之塘栖古镇
2019/12/04 职场文书