• position sticky与overflow冲突失效无作用,解决办法


    前言:

    position 可能失效的情况:
    1、须确定设置sticky元素的参考滚动父级元素
    2、指定 top, right, bottom 或 left 四个阈值其中之一(且达到设定的阈值),才可使粘性定位生效。否则其行为与相对定位相同;并且 top 和 bottom 同时设置时,top 生效的优先级高,left 和 right 同时设置时,left 的优先级高
    3、如果sticky元素的参考滚动父级元素是body,设定为 position: sticky 的元素的任意父节点的 overflow 属性必须是 visible,不能是hidden/auto/scroll/overlay,否则 position:sticky 不会生效;且包裹的最近的父容器高度要大于sticky 元素的高度;如果sticky元素的参考滚动父级元素是自己设置的内部元素,参考滚动父级元素可以设置overflow :/auto/scroll/overlay,且参考滚动父级元素的高度要比内部元素小

    问题现象

    在这里插入图片描述

    1:黄色板块:宽度超出可视宽度,可超出后支持左右滑动,其他板块不滑动;
    2:红色板块:需要实现吸顶效果;
    3:此时黄色板块css设置如下:

      width: 100%;
      padding: 20px 15px;
      overflow-x: auto; // 与吸顶效果冲突
      box-sizing: border-box;
      word-break: keep-all;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4:红色板块样式如下:

     padding: 10px 0;
     background: rgb(211, 200, 200);
     position: sticky;
     top: 0;
    
    • 1
    • 2
    • 3
    • 4

    5:position sticky失效

    问题解决

    思路:解决办法:新建一个克隆层,在移动下滑时候判断下滑高度生成克隆层,并在滚动栏到顶时删除克隆层;

    具体实现

    1:页面中基础配置

    // vue中
    <template>
      <div class="testCopyBox" id="testCopyBox">
      </div>
      </div>
      <div class="testBox">
          <div class="testBox2">测试测试测试测试数据很长要左右滚动且吸顶数据很长要左右滚动且吸顶数据很长要左右滚动且吸顶         </div>
      </div>
    </template>
    // css中
     }
     .testCopyBox {
       position: fixed;
       top: 40px;
       left: 10;
       width: 100%;
       overflow: auto;
       z-index: 1000;
       background: #fff;
          overflow-x: auto;
       box-sizing: border-box;
       word-break: keep-all;
        .testBox2 {
         padding: 30px 15px;
         background: rgb(211, 200, 200);
         position: sticky;
         top: 0;
       }
     }
     .testBox {
       width: 100%;
       padding: 20px 15px;
       overflow-x: auto;
       box-sizing: border-box;
       word-break: keep-all;
       margin-top: 50px;
        .testBox2 {
         padding: 30px 15px;
         background: rgb(211, 200, 200);
         position: sticky;
         top: 0;
       }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    2:监听页面滚动

    export default {
    	data () {
    		return {
    			topNavBg: {
            		backgroundColor: ''
          		}
    		}
    	},
    	// 滚动监听
    	mounted () {
        	window.addEventListener('scroll', this.handleScroll) // 监听页面滚动
        },
        methods: {
    		// 获取页面滚动距离
    	    handleScroll () {
    	        let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
    	        console.log(scrollTop, '滚动距离')
    	    }
    	},
    	// 滚动重置
        	beforeDestroy () {
          		window.removeEventListener('scroll', this.handleScroll)
        	},
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3:新建克隆层

    methods:{
    cloneDom () {
        var origin = document.getElementsByClassName('testBox2')[0]
        this.originNode = origin
        var originNewBox = document.getElementById('testCopyBox')
        // 若原本有则清空
        if(originNewBox.hasChildNodes()) {
            originNewBox.removeChild(originNewBox.firstChild)
        }
        // 否则进行克隆
        originNewBox.appendChild(origin)
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4:滚动删除克隆层

     // 获取页面滚动距离
    handleScroll () {
        let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
        console.log(scrollTop, '滚动距离')
        if (scrollTop > 60) {
            // 滚动到导航栏附近则克隆元素
            this.cloneDom()
        } else {
          // 否则删除克隆层 还原原始dom
            var origin = document.getElementsByClassName('testBox2')[0]
            var originNewBox = document.getElementById('testCopyBox')
            if(originNewBox.hasChildNodes()) {
                origin.appendChild(this.originNode)
                originNewBox.removeChild(originNewBox.firstChild)
            }
        }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    其他

    有可能页面操作较多,此原始dom存在左右滚动现象,故而为了完全复原在吸顶后也要监听到当前吸顶dom左右滚动距离,而上述方法会重置滚动距离为0,明显不太合适;具体实现方式如下:’

    实现

    1:可以给当前滚动设置ref
    :2:通过ref获取到原始dom scrollLeft的值
    3:通过this.$refs.[‘ref名称’].scrollLeft设置为上述获取到的值

  • 相关阅读:
    Seata分布式事务
    酷早报:9月5日Web3加密行业新闻大汇总
    【资源分享】官网imagent下载太慢?完整train、test、val资源分享
    Spark - 第4章 结构化API概述
    全屋Wi-Fi:一个谁也解决不好的痛点?
    Python Django 之连接 Mysql 数据库详解
    【222】MyQSL技术内幕 InnoDB 存储引擎第二版 笔记
    GLSL ES着色器语言 使用矢量和矩阵的相关规范
    Kindling-OriginX 在快手 Staging 环境的异常诊断效果分享
    力扣(LeetCode)1620. 网络信号最好的坐标(C++)
  • 原文地址:https://blog.csdn.net/duanhy_love/article/details/126160842