Vue仿京东移动端web版商品详情页滚动样式

要求:

  1. 页面顶部固定有 商品、评价、推荐、详情四个选项卡,对应四个部分的内容。
  2. 商品:显示轮播图、标题、价格等;评价:显示4条精选评价;推荐:显示两行三列6条推荐信息;详情:商品的详细介绍通常为富文本或一系列图片。
  3. 手动滚动页面,导航选项栏同样会自动切换对应样式。
  4. 当页面滚动距离为0时,导航选项栏透明度为0,且不可点击,每往下滚动20增加0.1,大于等于200时一直为1。(考虑性能可改为无级自动透明度或者每40增加0.2)
  5. 点任意选项卡会切换样式且滚动到对应的内容位置,
  6. 点击导航栏商品选项卡时时,滚动到0且透明度直接为0

预览效果

Android 详情页进入后台再次进入崩溃解决方式 移动端详情页_vue

 

绑定滚动事件

mounted() {
    window.addEventListener('scroll', this.handleScroll);
},
methods: {
    // 监听页面滚动
    handleScroll () {
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
    }
}

 

获取组件标签的位置

<div class="comment" ref="comment" id="comment"></div>

/**/

let recommendTop =  this.$refs.comment.offsetTop - 45;

 

使页面滚动到某组件标签

<a href="javascript:" @click="onScrollComment">评价</a>

onScrollComment(){
    document.documentElement.scrollTop = this.$refs.comment.offsetTop - 45;

  // behavior  类型String,表示滚动行为,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto,实测效果等同于instant
  window.scrollTo({top: this.$refs.detail.offsetTop - 45, behavior: "smooth" });
},

 

完整代码

样式细节未打磨,部分js代码可自行修改优化。疯狂滚动CPU占用比京东低。

1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>Document</title>
  9     <script src="vue.js"></script>
 10 </head>
 11 
 12 <body>
 13     <div id="app">
 14         <div :style="{opacity: opacity}" class="nav">
 15             <div class="header-new-title">
 16                 <nav class="detail_anchor">
 17                     <a href="javascript:" dtype="item" :class="{'active': active=='goods'}"
 18                         @click="onScrollGoods"><span>商品</span></a>
 19                     <a href="javascript:" dtype="comment" :class="{'active': active=='comment'}"
 20                         @click="onScrollComment"><span>评价</span></a>
 21                     <a href="javascript:" dtype="guess" :class="{'active': active=='recommend'}"
 22                         @click="onScrollRecommend"><span>推荐</span></a>
 23                     <a href="javascript:" dtype="detail" :class="{'active': active=='detail'}"
 24                         @click="onScrollDetail"><span>详情</span></a>
 25                 </nav>
 26             </div>
 27         </div>
 28 
 29         <div class="goods">
 30             <img style="width: 100%;" src="./apple-1.jpg" alt="">
 31             <div>我是商品标题</div>
 32             <div>我是商品价格</div>
 33             <div v-for="(item, index) in 10" :key="index">其他</div>
 34         </div>
 35         <hr>
 36 
 37         <div class="comment" ref="comment" id="comment">
 38             <div>精选评价</div>
 39             <div v-for="(item, index) in 4" :key="index">
 40                 <div class="title"><span class="fl">张若虚</span><span class="fr">2019-10-{{item}}</span></div>
 41                 <div class="content">春江潮水连海平,海上明月共潮生。</div>
 42             </div>
 43         </div>
 44         <hr>
 45 
 46         <div class="recommend" ref="recommend" id="recommend">
 47             <div>猜你喜欢</div>
 48             <img v-for="(item, index) in 6" :key="index" style="width: 33%;" src="./apple-1.jpg" alt="">
 49         </div>
 50         <hr>
 51 
 52         <div ref="detail">
 53             <div></div>
 54             <div>我是商品详情
 55                 <img v-for="(item, index) in 5" :key="index" style="width: 100%;" src="./apple-1.jpg" alt="">
 56             </div>
 57         </div>
 58 
 59         <div class="de_btn_bar">
 60             <div class="btn_group">
 61                 <div class="btn_group_item" style="width: 16%;">客服</div>
 62                 <div class="btn_group_item" style="width: 16%;">店铺</div>
 63                 <div class="btn_group_item" style="width: 18%;">购物车</div>
 64                 <div  class="btn_group_item add_cart">加入购物车</div>
 65                 <div class="btn_group_item now_buy">立即购买</div>
 66             </div>
 67         </div>
 68 
 69     </div>
 70     <script>
 71         var vm = new Vue({
 72             el: '#app',
 73             data: {
 74                 scrollTop: 0,
 75                 opacity: 0,
 76                 active: 'goods',
 77 
 78             },
 79             // 绑定滚动事件
 80             mounted() {
 81                 window.addEventListener('scroll', this.handleScroll);
 82             },
 83             methods: {
 84                 // 监听页面滚动
 85                 handleScroll() {
 86                     // 获取当前的滚动距离
 87                     var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
 88                     // console.log(scrollTop)
 89 
 90                     if (scrollTop < 200) {
 91                         // 当滚动距离小于200时,计算导航透明度,可以考虑修改为每20增加0.1
 92                         // this.opacity = (scrollTop / 200).toFixed(1);
 93                         this.opacity = scrollTop / 200;
 94                         this.active = 'goods';
 95                         return
 96                     } else {
 97                         this.opacity = 1
 98                     }
 99                     // 当滚动距离不小于200时,获取三个部分的顶部位置-45。
100                     let commentTop = this.$refs.comment.offsetTop - 45;
101                     let recommendTop = this.$refs.recommend.offsetTop - 45;
102                     let detailTop = this.$refs.detail.offsetTop - 45;
103                     // 计算滚动距离在哪个区间,修改this.active对应的样式名
104                     if (scrollTop < commentTop) { if (this.active != 'goods') this.active = 'goods'; }
105                     else if (scrollTop >= commentTop && scrollTop < recommendTop) { if (this.active != 'comment') this.active = 'comment'; }
106                     else if (scrollTop >= recommendTop && scrollTop < detailTop) { if (this.active != 'recommend') this.active = 'recommend'; }
107                     else if (scrollTop >= detailTop) { if (this.active != 'detail') this.active = 'detail'; }
108                 },
109                
110                 // 点击导航栏第一个商品选项卡时,直接滚动到0
111                 onScrollGoods() {
112                     // document.documentElement.scrollTop = 0;
113                     window.scrollTo({top: 0, behavior: "smooth" });
114                 },
115                 // 点击导航栏其他选项卡时,直接滚动到对应ref的offsetTop-45(导航栏高度)
116                 onScrollComment() {
117                     if (!this.opacity) return;
118                     window.scrollTo({top: this.$refs.comment.offsetTop - 45, behavior: "smooth" });
119                 },
120                 onScrollRecommend() {
121                     if (!this.opacity) return;
122                     window.scrollTo({top: this.$refs.recommend.offsetTop - 45, behavior: "smooth" });
123                 },
124                 onScrollDetail() {
125                     if (!this.opacity) return;
126                     //document.documentElement.scrollTop = this.$refs.detail.offsetTop - 45;
127                     // behavior  类型String,表示滚动行为,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto,实测效果等同于instant
128                     window.scrollTo({top: this.$refs.detail.offsetTop - 45, behavior: "smooth" });
129                     
130                 },
131             },
132         })
133     </script>
134     <style lang="less">
135         body {
136             margin: 0;
137         }
138         a {
139             text-decoration: none;
140             color: #252525;
141             -webkit-tap-highlight-color:transparent; 
142         }
143 
144         #app{
145             margin: 0 5px;
146         }
147         .nav {
148             height: 45px;
149             width: 100%;
150             background-color: #fff;
151             position: fixed;
152             z-index: 99;
153             opacity: 999;
154         }
155 
156         .detail_anchor {
157             display: -webkit-box;
158             display: -webkit-flex;
159             display: flex;
160             height: 44px;
161             line-height: 44px;
162             font-size: 14px;
163             color: #666;
164             box-shadow: 0 1px 6px rgba(0, 0, 0, .1);
165             justify-content: space-evenly;
166         }
167 
168         .header-new-title {
169             margin: 0 70px;
170             height: 44px;
171             font-size: 16px;
172             line-height: 44px;
173             text-align: center;
174             color: #333;
175             overflow: hidden;
176             text-overflow: ellipsis;
177             white-space: nowrap;
178         }
179 
180         .active {
181             color: #e4393c;
182         }
183 
184         .de_btn_bar{
185             height: 50px;
186             width: 100%;
187             background-color: #fff;
188             position: fixed;
189             z-index: 99;
190             bottom: 0;
191             }
192         .btn_group{
193             /* display: flex;
194             justify-content: space-evenly; */
195             height: 100%;
196         }
197         .btn_group_item{
198             display: inline-block;
199             height: 100%;
200             width: 25%;
201             margin-right: -5px;
202             padding: 0;
203             text-align: center;
204             line-height: 50px;
205         }
206         .add_cart{
207             color: #fff;
208             background: linear-gradient(138deg,#ffa600,#ffb000 77%,#ffbc00);
209         }
210         .now_buy{
211             color: #fff;
212             background: linear-gradient(-41deg,#ff4f18,#ff2000 24%,#f10000);
213         }
214     </style>
215 
216 </body>
217 
218 </html>

 

 

Android 详情页进入后台再次进入崩溃解决方式 移动端详情页_ci_02

Android 详情页进入后台再次进入崩溃解决方式 移动端详情页_选项卡_03