zoukankan      html  css  js  c++  java
  • 关于详情页的具体制作(六)

    已经实现了,点击详情页navbar的四个模块,会对应到每个商品中的相应位置。那么,我们现在想实现的是:比如滚到相应的尺寸模块或者评论时,navbar上的详情或者排列会自动变色。

    这个,主要用了以下思路来实现:

    首先,我们可以用一种很直观的方式来表达,首先先在scroll标签中设置probeType为3(因为在原来封装scroll的时候,将probeType的默认值设置为0,设置为3的时候可方便滚动且实时监听他的位置)

     <scroll class="content" ref="scroll" @scroll="contentscroll" :probe-type="3">

    之前在scroll.vue中曾经设置过监听滚动的位置的时候,发送出scroll事件,那么在此标签中,将监听contentscroll事件。

    那么,接下来我们来讲述下contentscroll事件应该如何设计,首先是比较复杂的逻辑关系的设定。首先回顾下,我们把一个在data中初始化一个数组themeTopY,且在imageLoad中,每次都push了每个模块的offsetTop值。

     data() {
        return {
          themeTopY:[0,0,0,0],
          currentIndex:0
        }
      }
     imageLoad() {
          this.refresh()
          // console.log("refresh no debounce")
            this.themeTopY =[ ]
            this.themeTopY.push(0)
            this.themeTopY.push(this.$refs.params.$el.offsetTop)
            this.themeTopY.push(this.$refs.comment.$el.offsetTop)
            this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
            console.log(this.themeTopY)
        }

    且,温故下原来封装的scroll:

    <template>
    <div class="wrapper" ref="wrapper">
     <div class="content">
       <slot></slot>
     </div>
    </div>
    </template>
    <!--//ref如果是绑定在组件中的,那么通过this.$refs.refname获取到的是一个组件对象-->
    <!--//ref如果绑定在普通元素中,那么会通过this.$refs.refname获取的一个元素对象-->
    <script>
    import BScroll from "better-scroll"
    export default {
      name: "scroll",
      props:['probeType',"pullUpLoad"],
      //'pullUpLoad'
      data(){
        return{
          scroll:null
        }
      },
      mounted(){
        //1.创建BScroll对象
    this.scroll = new BScroll(this.$refs.wrapper,{
    click:true,
      probeType:this.probeType,
      pullUpLoad:this.pullUpLoad
      //监听滚动到底部
    })
        // this.scroll.scrollTo(0,0)
        //2.监听滚动的位置
        this.scroll.on("scroll",(position)=>{
          // console.log(position);
          this.$emit("scroll",position)
        })
        //3.监听上拉加载事件
        // this.scroll.on("pullingUp",()=>{
        // this.$emit("pullingUp")
        // })
    //监听滚动到底部
    if(this.pullUpLoad){
      this.scroll.on("pullingUp",()=>{
        // console.log("监听");
        this.$emit("pullingUp")
      })
    
    
        }
      },
      methods: {
        scrollTo(x, y, time = 1000) {
          this.scroll.scrollTo(x, y, time)
        },
        // finishPullUp(){
        //   this.scroll.finishPullUp()
        // },
        refresh() {
          // console.log("----1----");
          this.scroll.refresh()
        },
        finishPullUp() {
        },
    
        // },
        getScrollY() {
          return this.scroll ? this.scroll.y : 0
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>

    后期,我们来处理下detail.vue中的contentscroll事件:

     contentscroll(position){
          // console.log(position);
          const positionY = -position.y
          for(let i= 0;i<this.themeTopY.length;i++){
            if(this.currentIndex !== i && i< this.themeTopY.length -1 && positionY >= this.themeTopY[i] && positionY < this.themeTopY[i+1] ||
              (i === this.themeTopY.length - 1 && positionY > this.themeTopY[i])){
              this.currentIndex = i;
              console.log(this.currentIndex);
              this.$refs.nav.currentIndex = i
            }
          }

    解释下上述的代码:

    首先,我们设定positionY为y轴上的position,由于其值在我测试后显示为负值,所以我直接在前面添加了一个负号。

    之后,设置了一个for循环,设置i小于themeTopy的长度。之后,我主要做了一个或逻辑,来处理它。左边,我设置,i小于themeTopY的长度,且当positionY大于等于i的offsetTop值,小于下标i+1的offsetTop值的时候,

    可以执行;或者i等于themeTopY的长度值减1的时候,也就是themeTopY的最后一个下标,且positionY大于最后一个数组元素的offsetTop时 ,也可以执行相应语句。之后,我在data中初始化了一个currentIndex,且在或逻辑的左边,设置当currentIndex的值不等于i的时候,才会执行相应左边的语句。之后,在执行时,我将i值赋予currentIndex,且将i值赋予navbar组件中的currentIndex值,我们再把detail中的navbar代码复现下:

    e>
      <div class="bbb">
        <navbar>
          <div slot="left" class="left" @click="backclick">
            <img src="../../../src/assets/img/back.svg">
          </div>
          <div slot="center" class="title">
            <div v-for="(item,index) in title"
                 class="aaa" :class="{active:index === currentIndex}" v-on:click="itemclick(index)">
              {{item}}
            </div>
          </div>
        </navbar>
      </div>
    </template>
    
    <script>
    import Navbar from "../../../src/components/common/navbar/navbar";
    export default {
      name: "detailnav",
      components: {Navbar},
      data(){
        return{
          title:['商品','参数','讨论','推荐'],
          currentIndex:0
        }
      },
      methods:{
        itemclick(index){
          this.currentIndex = index
          this.$emit("itemclick",index)
        },
        backclick(){
          this.$router.back()
        }
      }
    }
    </script>
    
    <style scoped>
    .title{
      display: flex;
      font-size: 13px;
    }
    .aaa{
      flex: 1;
    }
    .active{
      color: greenyellow;
    }
    .left img{
      margin-top: 10px;
    }
    .bbb{
      background-color: #f6f6f6;
      /*height: 100vh;*/
    
    }
    </style>

    那么,我们可以很清晰地发现,当事件中的i值赋予给navbar中的currentIndex,那么就可以实现滚动商品的四个详情模块的时候,亦可以实现滚动到哪个模块就激活navbar上的某个值。

    这个方法的话,逻辑还是有点杂糅,还有个更为简单的方法。

    我们可以在themeTopY这个数组的最后,直接push一个极大值,这样的话,直接在每个区间中执行就ok了,那我们来看下其代码实现。

     imageLoad() {
          this.refresh()
            this.themeTopY =[ ]
            this.themeTopY.push(0)
            this.themeTopY.push(this.$refs.params.$el.offsetTop)
            this.themeTopY.push(this.$refs.comment.$el.offsetTop)
            this.themeTopY.push(this.$refs.recommend.$el.offsetTop)
            this.themeTopY.push(Number.MAX_VALUE)
            console.log(this.themeTopY)
        }
    contentscroll(position) {
          // console.log(position);
          const positionY = -position.y
          for (let i = 0; i < this.themeTopY.length - 1; i++) {
            if (this.currentIndex !== i && (positionY >= this.themeTopY[i] && positionY < this.themeTopY[i + 1])) {
              this.currentIndex = i;
              // this.$refs.nav.currentIndex = this.currentIndex
              this.$refs.nav.currentIndex = i
            }
    
          }
    
        }

    我们看下上述代码,当我在数组最后push进了一个极大值的时候,我的逻辑也可以实现的很为简洁了。首先,我们将i的值限制,限制其小于themeTop的长度-1,之后我们只需要,将positionY的值限制在大于等于数组中i位置的offsetTop且小于i+1的位置即可。

    之后我们将i值赋予给nav中的currentIndex即可实现。

  • 相关阅读:
    Ubuntu 12.04 root账户开启及密码重设
    Notepad++ 开启「切分窗口」同时检视、比对两份文件
    第11章 Java异常与异常处理
    第10章 Java类的三大特性之一:多态
    第9章 Java类的三大特性之一:继承
    第8章 Java类的三大特性之一:封装
    第7章 类和对象
    java 经典程序 100 例
    第6章 Java类中的方法
    第5章 Java数组
  • 原文地址:https://www.cnblogs.com/ljylearnsmore/p/14307966.html
Copyright © 2011-2022 走看看