当前位置:   article > 正文

vue3在h5及小程序中滚动吸顶及(动态超出文本折叠)_vue h5 吸顶样式

vue h5 吸顶样式

 前言

vue3中滚动至一定高度tab按钮吸顶(h5中在header下、小程序中置顶),动态计算出后台返回的数据长度通过长度展示不同的样式

目录

一、templete部分

 二、script部分

三、style

四、展示效果

五、白屏问题


一、templete部分

  1. <template>
  2. <div @scroll="changeScroll" class="series_container">
  3. <v-header :headerOpt="headerOpt" :title="title"></v-header>
  4. <div id="bannerfix">
  5. <div class="banner">
  6. <img class="bannerImg" src="https://img-blog.csdnimg.cn/a432feb7b8c445dc8df68f71cabdc584.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png" alt="">
  7. </div>
  8. <div class="desbox">
  9. <div class="title">我是标题1111111111111111111111111111111111111111111111111111111</div>
  10. <div class="des_flex">
  11. <div ref="descontent" :class="['des',desFlag?'showFlag':'']">我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述我是详情描述</div>
  12. <div v-if="!showdesFlag" :class="['btn',desFlag?'':'showbtn']" @click="desFlag=!desFlag"></div>
  13. </div>
  14. </div>
  15. </div>
  16. <div :class="['series_main',scrollTopflag?'mainfix':'']">
  17. <div :class="['tab',scrollTopflag&&isWechat?'tabfix1':'',scrollTopflag&&!isWechat?'tabfix':'']">
  18. <div :class="['tab_btn',chooseTab==1?'tabActive':'']" @click="changeTab(1)">tab1<div class="border"></div></div>
  19. <div :class="['tab_btn',chooseTab==2?'tabActive':'']" @click="changeTab(2)">tab2</div>
  20. </div>
  21. <div v-if="chooseTab==1">
  22. <div class="series_detail">测试数据</div>
  23. </div>
  24. <div class="ser_list" v-if="chooseTab==2">
  25. <div class="ser_item" @click="toDetail(item)" v-for="(item,index) in 10" :key="index+'index'">
  26. <div class="lef">
  27. <img class="lef_img" src="https://p.qqan.com/up/2022-9/16644325731126722.jpg" alt="">
  28. </div>
  29. <div class="rig">
  30. <div>
  31. <div class="rigtitle">我是目录标题</div>
  32. </div>
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. </div>
  38. </template>

 二、script部分

  1. <script>
  2. import { defineComponent, nextTick, onMounted, ref } from 'vue'
  3. import { useRouter, useRoute } from 'vue-router'
  4. import { seriesCourseDetail } from "../../api/class/class";
  5. import header from '../../components/header.vue'
  6. export default defineComponent({
  7. components: {
  8. "v-header":header,
  9. },
  10. setup() {
  11. const router = useRouter(),
  12. route = useRoute()
  13. const title = ref(route.name || '')
  14. let seriesInfo=ref({})//详情信息
  15. let descontent=ref(null)//获取元素
  16. let desFlag=ref(false)//展示样式
  17. let chooseTab=ref(1)//选中tab
  18. let showdesFlag=ref(false)//是否展示按钮
  19. const u = navigator.userAgent;
  20. let isiOS=ref(false)
  21. let isWechat=ref(false)
  22. isWechat.value=sessionStorage.getItem("isminiPro") ? true : false;//是否小程序
  23. isiOS.value = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  24. const headerOpt = ref({
  25. backUrl: "",
  26. backQuery: {},
  27. });
  28. const query = ref({
  29. queryStr: "",
  30. paramObj: {},
  31. });
  32. let scrollTopflag=ref(false)//滚动flag
  33. let redirectUri = "";
  34. let openId = ref("");
  35. //对参数处理
  36. const getParams = () => {
  37. let urlQuery = window.location.href.split("?")[1];
  38. let arr = urlQuery.split("&");
  39. let paramObj = {};
  40. arr.forEach((item) => {
  41. let itemArr = item.split("=");
  42. paramObj[itemArr[0]] = itemArr[1];
  43. });
  44. query.value.queryStr = urlQuery; // 结果示例:code=code&seriesCode=123
  45. query.value.paramObj = paramObj; // 结果示例:{ code: code, seriesCode:123 }
  46. };
  47. //修改选中tab
  48. const changeTab=(index)=>{
  49. chooseTab.value=index
  50. }
  51. //获取信息
  52. const getseriesCourseDetail=(params)=>{
  53. seriesCourseDetail(params).then((res)=>{
  54. if(res.data){
  55. seriesInfo.value=res.data
  56. nextTick(()=>{
  57. init()
  58. })
  59. }
  60. })
  61. }
  62. let init=()=>{
  63. //计算课程介绍高度
  64. let lineHeight =22
  65. if(descontent.value.offsetHeight >lineHeight*1){
  66. desFlag.value=true
  67. }else{
  68. showdesFlag.value=true
  69. }
  70. }
  71. //fix顶部打开
  72. let changeScroll=(e)=>{
  73. let tarScro = e.target.scrollTop
  74. let fixheight=document.getElementById('bannerfix').clientHeight
  75. if(tarScro>=fixheight-10){
  76. // console.log('fix顶部了');
  77. scrollTopflag.value=true
  78. }else{
  79. scrollTopflag.value=false
  80. }
  81. }
  82. onMounted(() => {
  83. getParams()
  84. if(route.query.seriesCode){
  85. getseriesCourseDetail(route.query.seriesCode)
  86. }
  87. })
  88. return {
  89. title,
  90. chooseTab,
  91. seriesInfo,
  92. desFlag,
  93. descontent,
  94. showdesFlag,
  95. isiOS,
  96. isWechat,
  97. headerOpt,
  98. scrollTopflag,
  99. changeTab,
  100. changeScroll,
  101. }
  102. },
  103. })
  104. </script>

三、style

  1. .series_container{
  2. height: 100vh;
  3. background-color: #F6F8FA;
  4. padding-bottom: 1.2rem;
  5. box-sizing: border-box;
  6. overflow-x: hidden;
  7. overflow-y: auto;
  8. }
  9. .series_container1{
  10. padding-bottom: 0;
  11. }
  12. .series_container .banner{
  13. height: 5.64rem;
  14. display: -webkit-box;
  15. -webkit-box-pack: center;
  16. -webkit-box-align: center;
  17. overflow: hidden;
  18. }
  19. .series_container .banner .bannerImg{
  20. max-width: 100%;
  21. max-height: 100%;
  22. }
  23. .series_container .desbox{
  24. padding: .32rem .24rem;
  25. background-color: #fff;
  26. margin-bottom: .2rem;
  27. }
  28. .series_container .desbox .title{
  29. font-weight: 500;
  30. font-size: .32rem;
  31. line-height: .48rem;
  32. color: #000;
  33. word-break: break-all;
  34. }
  35. .series_container .desbox .des_flex{
  36. display: flex;
  37. /* align-items: center; */
  38. }
  39. .series_container .desbox .des_flex .des{
  40. flex:1;
  41. font-size: .28rem;
  42. line-height: .44rem;
  43. color: #999999;
  44. word-break: break-all;
  45. }
  46. .series_container .desbox .des_flex .showFlag{
  47. overflow:hidden;
  48. text-overflow:ellipsis;
  49. white-space: nowrap;
  50. /* display:-webkit-box;
  51. -webkit-box-orient:vertical;
  52. -webkit-line-clamp:1; */
  53. }
  54. .series_container .desbox .des_flex .btn{
  55. width: .40rem;
  56. height: .28rem;
  57. background: url('../../assets/arrow_down.png') center right no-repeat;
  58. background-size: .28rem .28rem;
  59. margin-top: .1rem;
  60. }
  61. .series_container .desbox .des_flex .showbtn{
  62. background: url('../../assets/arrow_up.png') center right no-repeat;
  63. background-size: .28rem .28rem;
  64. }
  65. .series_container .series_main{
  66. background-color: #fff;
  67. }
  68. .series_container .series_main .tab .tab_btn .border{
  69. width: .32rem;
  70. height: 0px;
  71. border: 0.02rem solid #EFEFEF;
  72. transform: rotate(90deg);
  73. position: absolute;
  74. right: -.16rem;
  75. }
  76. .series_container .series_main .tab{
  77. display: flex;
  78. height: 1rem;
  79. box-sizing: border-box;
  80. /* border-bottom: 0.01rem solid #EFEFEF; */
  81. }
  82. .series_container .tabfix{
  83. position: fixed;
  84. top: .88rem;
  85. width: 100%;
  86. background-color: #FFFFFF;
  87. z-index: 999;
  88. }
  89. .series_container .tabfix1{
  90. position: fixed;
  91. top: 0;
  92. width: 100%;
  93. background-color: #FFFFFF;
  94. z-index: 999;
  95. }
  96. .series_container .mainfix{
  97. padding-top: 1rem;
  98. }
  99. .series_container .series_main .tab .tab_btn{
  100. flex: 1;
  101. font-size: .28rem;
  102. line-height: .48rem;
  103. color: #151515;
  104. border-radius: .08rem;
  105. position: relative;
  106. display: flex;
  107. justify-content: center;
  108. align-items: center;
  109. }
  110. .series_container .series_main .tab .tabActive{
  111. color: #FF0095;
  112. font-weight: bold;
  113. }
  114. .series_container .series_detail{
  115. padding:0.24rem;
  116. min-height: 4.82rem;
  117. }
  118. .series_container .series_detail img{
  119. max-width: 100%;
  120. max-height: 100%;
  121. }
  122. .series_container .series_main .ser_list{
  123. padding: 0 .2rem;
  124. }
  125. .series_container .series_main .ser_item{
  126. padding: .32rem 0;
  127. border-bottom:.01rem solid #efefef ;
  128. display: flex;
  129. }
  130. .series_container .series_main .ser_item .lef{
  131. width: 2.16rem;
  132. height: 1.62rem;
  133. margin-right: .2rem;
  134. display: -webkit-box;
  135. -webkit-box-pack: center;
  136. -webkit-box-align: center;
  137. overflow: hidden;
  138. position: relative;
  139. border-radius: .08rem;
  140. }
  141. .series_container .series_main .ser_item .lef .lef_img{
  142. max-width: 100%;
  143. height: 100%;
  144. }
  145. .series_container .series_main .ser_item .rig{
  146. display: flex;
  147. flex-direction: column;
  148. justify-content: space-between;
  149. }
  150. .series_container .series_main .ser_item .rig .rigtitle{
  151. font-weight: 500;
  152. font-size: .28rem;
  153. width: 4.2rem;
  154. line-height: .44rem;
  155. color: #151515;
  156. overflow:hidden;
  157. text-overflow:ellipsis;
  158. white-space: nowrap;
  159. }

四、展示效果

五、白屏问题

以上代码经过测试在ios部分手机滑的快是切换存在白屏可能

换了一种写法

  1. onMounted(() => {
  2. window.addEventListener('scroll', changeScroll, false)
  3. })
  4. onUnmounted(() => {
  5. window.removeEventListener("scroll", changeScroll);
  6. });
  1. 去掉了templete写的滚动事件 @scroll="changeScroll",在事件委托中添加changeScroll事件,方法不变
  2. 在css中 添加 min-height: 100vh;

新增判断微信或者ios方法

  1. /* 是否微信环境 */
  2. export function wxEnv() {
  3. let ua = window.navigator.userAgent.toLowerCase();
  4. return ua.match(/MicroMessenger/i) == "micromessenger";
  5. }
  6. /* 是否ios终端 */
  7. export function isIOS() {
  8. let u = navigator.userAgent;
  9. return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  10. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/91761
推荐阅读
相关标签
  

闽ICP备14008679号