滚动条案例(点击跳转到指定地点,上下滑动跟随显示标题)

简介: 滚动条案例(点击跳转到指定地点,上下滑动跟随显示标题)

大致功能:

1. 点击按钮跳转至对应的位置
2. 滑动滚动条点击事件跟随当前位置的内容显示

具体思路:

1. 给按钮绑定点击事件并传递下标
2. 给需要跳转的位置进行 some 循环
3. 判断点击按钮传递过来的下标是否等于 some 循环的下标
4. 等于则根据距离顶部的距离进行跳转(把需要滑动元素的 scrollTop 赋值为条件成立的标签距离顶部的距离)
5. 滑动时点击事件跟随显示
6. 给需要滑动的标签绑定 scroll 事件
7. 给点击按钮进行 some 循环
8. 判断滑动标签距离顶部的距离是否大于需要跳转的位置距离顶部的距离
9. 判断成功则给当前标签选中,其他全部取消选中

代码:

<template>
  <div class="box" ref="box">
    <ul class="left" ref="left">
      <li
        v-for="(item, index) in listd"
        :key="index"
        ref="title"
        @click="meal(item, index)"
      >
        <router-link :to="'#' + index">
          <span ref="titles">{{ item }}</span>
        </router-link>
      </li>
    </ul>
    <ul class="right" ref="commodity" @scroll="scrolls">
      <li v-for="(item, index) in listds" :key="index">
        <p class="title" ref="sell" :id="index">
          <span>{{ item.name }}</span>
        </p>
        <div v-for="(items, index) in item.foods" :key="index" class="all">
          <div class="lileft" @click="details(items, item)">
            <img :src="items.image" alt="" />
            <span class="content"
              ><p class="name">{{ items.name }}</p>
              <p class="description">{{ items.description }}</p>
              <p class="sellCount">
                月售{{ items.sellCount }}<span>好评率{{ items.rating }}%</span>
              </p>
              <p class="price">
                <span class="newprice"><span>¥</span>{{ items.price }}</span>
                <span
                  class="oldPrice"
                  v-if="items.oldPrice == '' ? false : true"
                  >¥{{ items.oldPrice }}</span
                >
              </p></span
            >
          </div>
          <div class="liright">
            <button v-show="num[index] > 0" @click="add(items, index)">
              <img src="@/assets/商品/remove_circle_outline.svg" alt="" />
            </button>
            <span ref="num" v-show="num[index] > 0">{{ num[index] }}</span>
            <!-- <span ref="num" v-show="num == 0"></span> -->
            <button @click="addition(items, index)">
              <img src="@/assets/商品/add_circle.svg" alt="" />
            </button>
          </div>
        </div>
      </li>
    </ul>
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  data() {
    return {
      listd: [],
      listds: [],
      setmeal: "热销榜",
      scrollHeights: 0,
      heightArr: [0, 0],
      num: [],
    };
  },
  created() {
    if (this.$route.query.name) {
      this.setmeal = this.$route.query.name;
    } else {
      this.setmeal = "热销榜";
    }
    this.request();
    this.requestgoods();
  },
  mounted() {
    if (localStorage.getItem("num")) {
      this.num = localStorage.getItem("num").split(",");
    }
    if (this.$refs.box.scrollHeight < 860) {
      this.$refs.left.className = "left lefts";
      let arr = 352 - this.$refs.left.offsetTop + 860;
      this.$refs.commodity.style.height = arr + "px";
    }
  },
  computed: {
    ...mapState(["pitch"]),
  },
  methods: {
    request() {
      this.$axios.get(`/before/goods/help`).then((err) => {
        console.log(err.data);
        this.listd = err.data;
      });
    },
    requestgoods() {
      this.$axios.get(`/before/goods`).then((err) => {
        this.listds = err.data;
        this.listds.some((item) => {
          item.foods.some((items) => {
            this.num.push(0);
          });
        });
      });
    },
    meal(items, indexs) {
      this.$refs.sell.some((item, index) => {
        if (indexs == index) {
          this.$refs.commodity.scrollTop = item.offsetTop - 350;
        }
      });
    },
    scrolls() {
      this.$refs.title.some((item, index) => {
        if (
          this.$refs.commodity.scrollTop >
          this.$refs.sell[index].offsetTop - 352
        ) {
          this.$refs.title.some((item) => {
            item.style.backgroundColor = "#f3f5f7";
          });
          item.style.backgroundColor = "#fff";
        }
      });
    },
    addition(item, index) {
      let num = 0;
      for (let i = 0; i < this.pitch.length; i++) {
        if (this.pitch[i].name == item.name) {
          num = i;
        }
        if (item.name == this.pitch[i].name) {
          console.log(item.name);
        }
      }
      this.$store.commit("addshopping", item);
      this.$set(this.num, index, this.pitch[num].num);
      localStorage.setItem("num", this.num);
    },
    add(item, index) {
      let num = 0;
      for (let i = 0; i < this.pitch.length; i++) {
        if (this.pitch[i].name == item.name) {
          num = i;
        }
        if (item.name == this.pitch[i].name) {
          console.log(item.name);
        }
      }
      this.$store.commit("addj", num);
      this.$set(this.num, index, this.pitch[num].num);
      localStorage.setItem("num", this.num);
    },
    details(item, title) {
      console.log(item.name);
      this.$router.push({
        name: "Details",
        query: { title: title.name, name: item.name },
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.box {
  width: 100%;
  // height: 100%;
  display: flex;
  .lefts {
    overflow: auto !important;
    height: 100% !important;
  }
  .left {
    width: 1.7rem;
    height: 8.6rem;
    overflow: auto;
    scrollbar-width: none;
    li {
      list-style: none;
      width: 1.6rem;
      height: 1.08rem;
      display: flex;
      flex-wrap: wrap;
      background-color: #f3f5f7;
      a {
        width: 100%;
        height: 100%;
        padding: 0 0.24rem;
        color: rgba(7, 17, 27, 0.8);
        display: flex;
        align-items: center;
        text-decoration: none;
        span {
          width: 1.6rem;
          height: 1.08rem;
          font-size: 0.24rem;
          line-height: 0.28rem;
          display: flex;
          align-items: center;
          font-weight: 200;
          color: rgba(7, 17, 27, 0.8);
          border-bottom: 0.01rem solid rgba(7, 17, 27, 0.1);
        }
      }
    }
  }
  .left::-webkit-scrollbar {
    display: none;
  }
  .right {
    width: 100%;
    height: 8.6rem;
    overflow: auto;
    // padding-bottom: 1rem;
    li {
      list-style: none;
      .title {
        width: 100%;
        height: 0.52rem;
        background-color: #f3f5f7;
        border-left: 0.04rem solid #d9dde1;
        span {
          margin-left: 0.28rem;
          font-size: 0.24rem;
          line-height: 0.52rem;
          color: rgb(147, 153, 159);
        }
      }
      .all {
        list-style: none;
        margin: 0 0.36rem;
        padding: 0.36rem 0;
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        border-bottom: 0.01rem solid rgba(7, 17, 27, 0.1);
        .lileft {
          display: flex;
          img {
            width: 1.15rem;
            height: 1.15rem;
          }
          .content {
            margin: 0.04rem 0 0 0.2rem;
            .name {
              font-size: 0.28rem;
              color: rgba(7, 17, 27);
              line-height: 0.28rem;
            }
            .description {
              font-size: 0.2rem;
              color: rgb(147, 153, 159);
              line-height: 0.2rem;
              margin: 0.16rem 0;
            }
            .sellCount {
              font-size: 0.2rem;
              color: rgb(147, 153, 159);
              line-height: 0.2rem;
              span {
                font-size: 0.2rem;
                line-height: 0.2rem;
                margin-left: 0.24rem;
              }
            }
            .price {
              .newprice {
                font-size: 0.28rem;
                line-height: 0.48rem;
                color: rgb(240, 20, 20);
                font-weight: 700;
                span {
                  font-size: 0.2rem;
                }
              }
              .oldPrice {
                font-size: 0.2rem;
                line-height: 0.48rem;
                color: rgb(147, 153, 159);
                font-weight: 700;
                margin-left: 0.16rem;
                text-decoration: line-through;
              }
            }
          }
        }
        .liright {
          display: flex;
          align-items: center;
          button {
            background-color: #fff;
            border: none;
            overflow: hidden;
            img {
              width: 0.48rem;
              height: 0.48rem;
              filter: drop-shadow(rgb(0, 160, 220) 100px 0);
              transform: translateX(-100px);
            }
          }
          span {
            width: 0.48rem;
            // height: 0.48rem;
            text-align: center;
            font-size: 0.2rem;
            line-height: 0.48rem;
            color: rgb(147, 153, 159);
          }
        }
      }
    }
  }
}
</style>

以上就是滚动条案例的代码,不懂得也可以在评论区里问我,以后会持续添加一些新的功能,敬请关注。

相关文章
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
|
4月前
Axure 列表左右滑动交互-删除、置顶
Axure 列表左右滑动交互-删除、置顶
234 0
|
7月前
|
前端开发 JavaScript 定位技术
高德地图实现-自定义信息窗+窗体点击事件
高德地图实现-自定义信息窗+窗体点击事件
539 0
uniapp滚动条置顶效果、自定义页面滚动条的位置(整理)
uniapp滚动条置顶效果、自定义页面滚动条的位置(整理)
|
前端开发
前端——背景图片显示以及悬浮状态下变色的情况
前端——背景图片显示以及悬浮状态下变色的情况
|
小程序 算法 前端开发
小程序之移花宫-自定义底部标签图标---【浅入深出系列005】
小程序之移花宫-自定义底部标签图标---【浅入深出系列005】
|
容器
使用导航菜单如何实现在多个页面下左边导航菜单右边内容的效果
使用导航菜单如何实现在多个页面下左边导航菜单右边内容的效果
206 0
|
前端开发 视频直播 JavaScript
制作侧边栏显示和隐藏效果
公司最近在做一个视频直播的功能,里面有个页面样式是需要点击收起侧边栏的,整体效果如图: 那么如何制作呢,参考了网上的代码,我发现很简单,下面就是我制作的代码: 返回 ...
1562 0
点击图片或者鼠标划过切换样式的另一种写法
点击图片或者鼠标划过切换样式的另一种写法
69 0
|
JSON 数据格式
底部弹出PopupWindow+地址三级联动,多问题全面分析,详细注释
底部弹出PopupWindow+地址三级联动,多问题全面分析,详细注释
181 0
底部弹出PopupWindow+地址三级联动,多问题全面分析,详细注释