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

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

要求:

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

 

绑定滚动事件

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(){
    ocument.documentElement.scrollTop = this.$refs.comment.offsetTop - 45;
},

 

完整代码

样式细节未打磨,部分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" >
 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" >
 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" >
 56             </div>
 57         </div>
 58 
 59 
 60 
 61     </div>
 62     <script>
 63         var vm = new Vue({
 64             el: ‘#app‘,
 65             data: {
 66                 scrollTop: 0,
 67                 opacity: 0,
 68                 active: ‘goods‘,
 69 
 70             },
 71             // 绑定滚动事件
 72             mounted() {
 73                 window.addEventListener(‘scroll‘, this.handleScroll);
 74             },
 75             methods: {
 76                 // 监听页面滚动
 77                 handleScroll() {
 78                     // 获取当前的滚动距离
 79                     var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
 80                     //console.log(scrollTop)
 81 
 82                     if (scrollTop < 200) {
 83                         // 当滚动距离小于200时,计算导航透明度,可以考虑修改为每20增加0.1
 84                         // this.opacity = (scrollTop / 200).toFixed(1);
 85                         this.opacity = scrollTop / 200;
 86                         this.active = ‘goods‘;
 87                         return
 88                     } else {
 89                         this.opacity = 1
 90                     }
 91                     // 当滚动距离不小于200时,获取三个部分的顶部位置-45。
 92                     let commentTop = this.$refs.comment.offsetTop - 45;
 93                     let recommendTop = this.$refs.recommend.offsetTop - 45;
 94                     let detailTop = this.$refs.detail.offsetTop - 45;
 95                     // 计算滚动距离在哪个区间,修改this.active对应的样式名
 96                     if (scrollTop < commentTop) { if (this.active != ‘goods‘) this.active = ‘goods‘; }
 97                     else if (scrollTop >= commentTop && scrollTop < recommendTop) { if (this.active != ‘comment‘) this.active = ‘comment‘; }
 98                     else if (scrollTop >= recommendTop && scrollTop < detailTop) { if (this.active != ‘recommend‘) this.active = ‘recommend‘; }
 99                     else if (scrollTop >= detailTop) { if (this.active != ‘detail‘) this.active = ‘detail‘; }
100                 },
101                 // 点击导航栏第一个商品选项卡时,直接滚动到0
102                 onScrollGoods() {
103                     document.documentElement.scrollTop = 0;
104                 },
105                 // 点击导航栏其他选项卡时,直接滚动到对应ref的offsetTop-45(导航栏高度)
106                 onScrollComment() {
107                     if (!this.opacity) return;
108                     document.documentElement.scrollTop = this.$refs.comment.offsetTop - 45;
109                 },
110                 onScrollRecommend() {
111                     if (!this.opacity) return;
112                     document.documentElement.scrollTop = this.$refs.recommend.offsetTop - 45;
113                 },
114                 onScrollDetail() {
115                     if (!this.opacity) return;
116                     document.documentElement.scrollTop = this.$refs.detail.offsetTop - 45;
117                 },
118             },
119         })
120     </script>
121     <style lang="less">
122         body {
123             margin: 0;
124         }
125         a {
126             text-decoration: none;
127             color: #2c3e50;
128         }
129         #app{
130             margin: 0 5px;
131         }
132         .nav {
133             height: 45px;
134             width: 100%;
135             background-color: #fff;
136             position: fixed;
137             border-bottom: 45px;
138             z-index: 99;
139             opacity: 999;
140         }
141 
142         .detail_anchor {
143             display: -webkit-box;
144             display: -webkit-flex;
145             display: flex;
146             height: 44px;
147             line-height: 44px;
148             font-size: 14px;
149             color: #666;
150             box-shadow: 0 1px 6px rgba(0, 0, 0, .1);
151             justify-content: space-evenly;
152         }
153 
154         .header-new-title {
155             margin: 0 70px;
156             height: 44px;
157             font-size: 16px;
158             line-height: 44px;
159             text-align: center;
160             color: #333;
161             overflow: hidden;
162             text-overflow: ellipsis;
163             white-space: nowrap;
164         }
165 
166         .active {
167             color: #e4393c;
168         }
169     </style>
170 
171 </body>
172 
173 </html>

 

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

 

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

上一篇:Qt编写的项目作品10-RTSP播放器+视频监控(android版本)


下一篇:[译]How to handle background services in ANDROID O?