Browse Source

商品分类锚点交互调整

feature/feature-compatible
wenghaocan 7 years ago
parent
commit
80c51775bd
5 changed files with 144 additions and 145 deletions
  1. 1
      package.json
  2. 9
      src/assets/styles/style.css
  3. 49
      src/common/rem.js
  4. 224
      src/view/goods-classify.vue
  5. 6
      src/view/home.vue

1
package.json

@ -30,6 +30,7 @@
"babel-preset-env": "^1.6.0", "babel-preset-env": "^1.6.0",
"babel-preset-stage-2": "^6.24.1", "babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.26.0", "babel-register": "^6.26.0",
"better-scroll": "^1.13.0",
"chalk": "^1.1.3", "chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0", "connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1", "copy-webpack-plugin": "^4.0.1",

9
src/assets/styles/style.css

@ -331,6 +331,15 @@ html,body {
.f-inb { .f-inb {
display: inline-block; display: inline-block;
} }
.weui-toast {
width: 100%;
min-height: 100% !important;
overflow: hidden;
top: 0;
}
.weui-icon_toast.weui-loading {
margin-top: 75%;
}
@media (-webkit-min-device-pixel-ratio: 2) { @media (-webkit-min-device-pixel-ratio: 2) {
.f-bb-gray::after { .f-bb-gray::after {
height: 1px; height: 1px;

49
src/common/rem.js

@ -1,13 +1,36 @@
window.onload = function(){
/*720稿稿;100100
为了以后好算,比如你测量的一个宽度是100px,就可以写为1rem,以及1px=0.01rem等等*/
getRem(750,100)
};
window.onresize = function(){
getRem(750,100)
};
function getRem(pwidth,prem){
var html = document.getElementsByTagName("html")[0];
var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
html.style.fontSize = oWidth/pwidth*prem + "px";
}
(function(win) {
var doc = win.document;
var docEl = doc.documentElement;
var tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
if (width > 750) {
// 最大宽度
width = 750;
}
var rem = width / 7.5;
docEl.style.fontSize = Math.round(rem) + "px";
}
win.addEventListener(
"resize",
function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
},
false
);
win.addEventListener(
"pageshow",
function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
},
false
);
refreshRem();
})(window);

224
src/view/goods-classify.vue

@ -3,10 +3,10 @@
<div class="top f-bb-gray"> <div class="top f-bb-gray">
<img src="../assets/images/icon/arrow-left.png" v-on:click="goBack"/>商品分类 <img src="../assets/images/icon/arrow-left.png" v-on:click="goBack"/>商品分类
</div> </div>
<div class="content cate-content">
<div class="left">
<div class="content">
<div class="left" ref="menuWrapper">
<ul> <ul>
<li v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" :class="{ on : isActive === index}" @click="jump(index)">
<li v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" :class="{'on': currentIndex === index}" @click="selectMenu(index,$event)">
<a href="javascript:void(0)"> <a href="javascript:void(0)">
{{item.combinationName}} {{item.combinationName}}
<img src="../assets/images/icon/hot.png" class="i-hot" v-if="item.label == '2'" /> <img src="../assets/images/icon/hot.png" class="i-hot" v-if="item.label == '2'" />
@ -14,55 +14,68 @@
</a> </a>
</li> </li>
</ul> </ul>
</div>
<div class="cate-list right" :scrollTop.prop="scrollTop">
<div v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" class="cate-item">
<p class="title" :id="'anchor-'+index">{{item.combinationName}}</p>
<div class="f-relative f-all-1px" v-for="(goods,k) in item.goodsList" :key="k">
<div class="item f-flex">
<a :href="'/mall/web/vgoods/detail/' + goods.goodsNo">
<img :src=" imghost + goods.bannerImgs" class="thumb"/>
</a>
<div class="info f-flex">
<div>
<p class="title f-ellipsis-1">{{goods.name}}</p>
<p class="rule">{{goods.shortDesc}}</p>
<div class="full" v-if="toJSON(goods.smallLabel)"><i>{{toJSON(goods.smallLabel)}}</i></div>
</div>
<div class="f-flex">
<p class="price">
<span><span class="money"></span>{{goods.price/100}}</span>
</p>
<p class="cost" v-if="goods.originalPrice">{{goods.originalPrice/100}}</p>
</div>
</div>
</div>
<div class="right" ref="foodWrapper">
<div>
<div v-if="goodsList.length != 0" v-for="(item,index) in goodsList" :key="index" class="food-list-hook">
<p class="title">{{item.combinationName}}</p>
<div class="f-relative f-all-1px" v-for="(goods,k) in item.goodsList" :key="k">
<div class="item f-flex">
<a :href="'/mall/web/vgoods/detail/' + goods.goodsNo">
<img :src=" imghost + goods.bannerImgs" class="thumb"/>
</a>
<div class="info f-flex">
<div>
<p class="title f-ellipsis-1">{{goods.name}}</p>
<p class="rule">{{goods.shortDesc}}</p>
<div class="full" v-if="toJSON(goods.smallLabel)"><i>{{toJSON(goods.smallLabel)}}</i></div>
</div>
<div class="f-flex">
<p class="price">
<span><span class="money"></span>{{goods.price/100}}</span>
</p>
<p class="cost" v-if="goods.originalPrice">{{goods.originalPrice/100}}</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
</div> </div>
<!-- Loading --> <!-- Loading -->
<div class="Loading-box">
<loading v-model="showLoading" text="loading"></loading>
</div>
<loading :show="showLoading" text="loading"></loading>
</div> </div>
</template> </template>
<script> <script>
import goodsApi from "../models/goods-model.js"; import goodsApi from "../models/goods-model.js";
import { Alert,Toast,Popup,Loading } from "vux"; import { Alert,Toast,Popup,Loading } from "vux";
import BScroll from 'better-scroll';
export default { export default {
data() { data() {
return { return {
no: 0, no: 0,
id: 0, id: 0,
c_no: 0, c_no: 0,
showLoading: true,
showLoading: false,
goodsList: [], goodsList: [],
imghost: "http://medou.oss-cn-shenzhen.aliyuncs.com/", imghost: "http://medou.oss-cn-shenzhen.aliyuncs.com/",
isActive: '',
container: document.querySelectorAll('.cate-list')
listHeight: [], //
scrollY: {}
} }
}, },
computed: {
currentIndex () {
const { scrollY, listHeight } = this
let index = listHeight.findIndex((height, index) => {
return scrollY >= listHeight[index] && scrollY < listHeight[index + 1]
})
if (scrollY > listHeight[index] + 50) {
index++
}
return index
}
},
components: { components: {
Toast, Toast,
Popup, Popup,
@ -96,47 +109,7 @@
this.$vux.toast.text(res.msg,"middle"); this.$vux.toast.text(res.msg,"middle");
} }
}); });
this.$nextTick(function(){
for (let i = 0; i < this.goodsList.length; i++) {
if(this.goodsList[i].combinationNo == this.c_no) {
this.jump(i)
}
}
})
}, },
jump(index){
const cateItem = document.querySelectorAll('.cate-item');
let total = cateItem[index].offsetTop;
let distance = this.container.scrollTop // (this.container便.cate-list,便)
let step = total / 20;
this.isActive = index; //
const _this = this;
if (total > distance) {
smoothDown()
} else {
let newTotal = distance - total
step = newTotal / 50
smoothUp()
}
function smoothDown () {
if (distance < total) {
distance += step
_this.scrollTop = distance - 60
setTimeout(smoothDown, 10);
} else {
_this.scrollTop = total - 60
}
}
function smoothUp () {
if (distance > total) {
distance -= step
_this.scrollTop = distance - 60
setTimeout(smoothUp, 10)
} else {
_this.scrollTop = total - 60
}
}
},
toJSON (data){ toJSON (data){
if (data){ if (data){
return JSON.parse(data)[0].labelText return JSON.parse(data)[0].labelText
@ -144,54 +117,56 @@
return ; return ;
} }
}, },
onScroll () {
var _this = this;
_this.itemVal.forEach(function(obj, i){
_this.scrollTop = _this.container.scrollTop;
if(_this.scrollTop >= obj.top && _this.scrollTop < (obj.top + obj.height-10)){
// scrollTop
_this.isActive = obj.index;
}
})
_initScroll() {
this.menuScroll = new BScroll(this.$refs.menuWrapper,{
click:true //better-scroll
});
this.foodsScroll = new BScroll(this.$refs.foodWrapper,{
click:true, //better-scroll
probeType : 3 //better-scrollscroll
});
this.foodsScroll.on('scroll', (pos) => {
this.scrollY = Math.abs(Math.round(pos.y));
})
}, },
currentStick () {
const {dishId} = this.$route.query;
const cateContent = document.querySelectorAll('.cate-content');
const _this = this;
cateContent.forEach(function(v, i){
if(v.id == dishId){
_this.scrollTop = v.offsetTop;
}
})
},
scroll () {
// scroll
const _this = this;
setTimeout(function(){
_this.currentStick();
const rightItem = document.querySelectorAll('.cate-item');
const catelist = document.querySelectorAll('.cate-list')[0];
var length = rightItem.length;
var height = rightItem[length-1].offsetHeight;
var scrollHeight = document.querySelectorAll('.cate-menu-wrapper')[0].offsetHeight;
// ()
if (height < scrollHeight) {
rightItem[length-1].style.height = scrollHeight+'px';
}
var arr =[];
rightItem.forEach(function(v, i){
arr.push({top: v.offsetTop, height: v.offsetHeight, index: i});
})
_this.itemVal = arr;
const cateList = document.querySelectorAll('.cate-list')[0];
cateList.addEventListener('scroll', _this.onScroll);
_this.container = cateList;
}, 500)
}
_calculateHeight() {
//food-list-hookfood,
let foodList = this.$refs.foodWrapper.getElementsByClassName("food-list-hook");
let height = 0;
this.listHeight.push(height);
//listHeight
for (let i = 0; i < foodList.length; i++) {
let item = foodList[i];
height += item.clientHeight;
this.listHeight.push(height);
}
},
selectMenu(index, event) {
if(event && !event._constructed) {
return ;
}
let foodList = this.$refs.foodWrapper.getElementsByClassName("food-list-hook");
let el = foodList[index];
this.foodsScroll.scrollToElement(el,300)
},
autoSelect() {
for (let i = 0; i < this.goodsList.length; i++) {
if(this.goodsList[i].combinationNo == this.c_no) {
this.selectMenu(i)
}
}
}
}, },
mounted() { mounted() {
this.getParams() this.getParams()
this.scroll()
window.onload = () =>{
//scroll
this._initScroll()
//
this._calculateHeight();
//
this.autoSelect()
}
}, },
} }
</script> </script>
@ -219,11 +194,13 @@
width: 100%; width: 100%;
display: flex; display: flex;
height: calc(100vh - 0.9rem); height: calc(100vh - 0.9rem);
-webkit-overflow-scrolling: touch;
.left { .left {
width: 1.74rem; width: 1.74rem;
background-color: #F3F3F3; background-color: #F3F3F3;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
-webkit-overflow-scrolling: touch;
ul { ul {
li { li {
width: 1.74rem; width: 1.74rem;
@ -259,6 +236,7 @@
.right { .right {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
-webkit-overflow-scrolling: touch;
padding: 0.2rem 0.22rem 0; padding: 0.2rem 0.22rem 0;
width: calc(100% - 1.74rem); width: calc(100% - 1.74rem);
box-sizing: border-box; box-sizing: border-box;
@ -324,16 +302,4 @@
} }
} }
} }
.Loading-box {
.weui-toast {
width: 100%;
min-height: 100% !important;
overflow: hidden;
top: 0;
}
.weui-icon_toast.weui-loading {
margin-top: 75%;
}
}
</style> </style>

6
src/view/home.vue

@ -57,7 +57,7 @@
</div> </div>
<div class="new-card" :class="{'new-card-first': index == 0}" v-for="(item,index) in goodsList" :key="index"> <div class="new-card" :class="{'new-card-first': index == 0}" v-for="(item,index) in goodsList" :key="index">
<div class="new-card-top"> <div class="new-card-top">
<img :src=" imghost + item.list[0].categoryImage">
<img :src=" imghost + item.list[0].combinationImage">
</div> </div>
<ul class="card-list"> <ul class="card-list">
<li v-for="item1 in item.list"> <li v-for="item1 in item.list">
@ -201,7 +201,7 @@
let goodsList = res.response.goodsList let goodsList = res.response.goodsList
let arr = []; let arr = [];
for(let i=0;i<goodsList.length;i++){ for(let i=0;i<goodsList.length;i++){
goodsList[i].categoryNo&&goodsList[i].isRelease==1?arr.push(goodsList[i].categoryNo):"";
goodsList[i].combinationNo&&goodsList[i].isRelease==1?arr.push(goodsList[i].combinationNo):"";
} }
let set =new Set(arr); let set =new Set(arr);
let list=Array.from(set); let list=Array.from(set);
@ -213,7 +213,7 @@
}) })
for(let x=0;x<goodsList.length;x++){ for(let x=0;x<goodsList.length;x++){
if(lastList[i].type==goodsList[x].categoryNo&&goodsList[x].isRelease==1){
if(lastList[i].type==goodsList[x].combinationNo&&goodsList[x].isRelease==1){
lastList[i].list.push(goodsList[x]); lastList[i].list.push(goodsList[x]);
} }
} }

Loading…
Cancel
Save