导航栏滚动效果应用

10 篇文章 1 订阅

效果:1.左边数据滚动到相应位置 右边导航对应
2.点击右侧导航 自动定位该数据
在这里插入图片描述
效果1 主要代码:
js代码:

 mounted() {
    window.addEventListener('scroll', this.checkScroll);
  },
 // 页面滚动对应字母导航
    checkScroll() {
      this.letterArr.forEach((item) => {
        // 判断数据是否含有该字母
        this.detailList.forEach((li) => {
          // 如果有
          if (li.letter == item) {
            var cont1 = $(`.main_table .letter${item}`).offset().top - 100;
            var className = $(`.main_table .letter${item}`).attr('class');
            className = className.substr(className.length - 1, 1);
            var cont2 =
              $(`.main_table .letter${item}`).offset().top +
              $(`.main_table .letter${item}`).height() -
              100;
            var t =
              document.documentElement.scrollTop || document.body.scrollTop;
            if (t >= cont1 && t <= cont2) {
              this.letterArr.forEach((item, i) => {
                if (item == className) {
                  this.currentletter = i;
                }
              });
            } else {
            }
          }
        });
      });
    },

效果2 主要代码:
js代码:

  toCurrentletter(i) {
      this.currentletter = i;
      this.detailList.forEach((item) => {
        if (item.letter == this.letterArr[i]) {
          $('body,html').animate(
            { scrollTop: $(`.letter${this.letterArr[i]}`).offset().top - 80 },
            1000,
          );
        }
      });
    },

下面是全部代码:

<template>
  <div class="service_contain">
    <Spin size="large" fix v-if="spinShow"></Spin>

    <div class="bgImg">
      <img src="../assets/img/service/servicebanner.png" alt="" />
      <span class="banner_title">
        {{ $store.state.isChinese ? '服务中心' : 'Service center' }}</span
      >
    </div>

    <div class="carousel">
      <div
        class="businessBox"
        @mouseenter="moreEnter(i)"
        @mouseleave="moreLeave(i)"
        v-for="(item, i) in navList"
        :key="i + item.src"
        @click="toChangeTabs(item, i)"
      >
        <div
          style="height:100%"
          :class="{ colorLineHeight: item.id == moduleId }"
        >
          <div class="triangle" v-if="item.id == moduleId"></div>
          <div class="businessBox_content">
            <img
              :src="item.isChangeHeight ? item.hoverSrc : item.src"
              alt=""
              :key="imgNum"
            />
            <h3
              class="title"
              :class="{ colorfont: item.id == moduleId }"
              style="text-align:center"
            >
              {{ $store.state.isChinese ? item.name : item.nameEn }}
            </h3>
            <h4
              :class="{ colorfont: item.id == moduleId }"
              style="text-align:center"
            >
              {{ $store.state.isChinese ? item.summary : item.summaryEn }}
            </h4>
          </div>
        </div>
      </div>
    </div>

    <!-- detail -->
    <div class="companyList">
      <h2 style="margin:30px 5%">
        {{ $store.state.isChinese ? '合格服务商' : 'Qualified service provider'
        }}<span style="color:#999999">
          {{
            $store.state.isChinese
              ? '按首字母排序(排名不分先后)'
              : 'Alphabetical order'
          }}</span
        >

        <RadioGroup
          v-model="radioGroup"
          style="margin-left:20px;font-weight:400"
        >
          <Radio
            :label="$store.state.isChinese ? '查看全部' : 'Look at all'"
          ></Radio>
          <Radio
            :label="$store.state.isChinese ? '查看收藏' : 'See the collection'"
            style="margin-left:20px;"
          ></Radio>
        </RadioGroup>
      </h2>

      <div class="main_table">
        <ul
          v-for="(item, i) in detailList"
          :key="i + 'pp'"
          :class="'letter' + item.letter"
        >
          <li
            v-for="(li, m) in item.list"
            :key="m + 'yy'"
            @click="openUrl(li.naviUrl)"
          >
            <div style="color:#666666;width:200px">
              {{ li.isletter ? li.letter : '' }}
            </div>
            <div
              class="bg_div"
              style="border-bottom: 1px solid #F0F0F0;padding-left:50px;width:300px"
            >
              <span class="logo">{{ item.letter }} </span>
            </div>
            <div
              class="bg_div"
              style=" border-bottom: 1px solid #F0F0F0;  overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;"
            >
              {{ $store.state.isChinese ? li.naviName : li.naviNameEn }}
            </div>
            <div class="bg_div" style=" border-bottom: 1px solid #F0F0F0;">
              {{ $store.state.isChinese ? li.country : li.companyEn }}
            </div>
            <div
              class="bg_div"
              style=" border-bottom: 1px solid #F0F0F0;  overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;"
            >
              {{ li.naviUrl }}
            </div>
            <div
              class="bg_div"
              style=" border-bottom: 1px solid #F0F0F0;text-align: right;width:100px"
            >
              <Icon
                type="ios-heart"
                :color="li.iscolor ? 'red' : '#BEBEBE'"
                @click.stop="collection(i, m)"
                :key="colorNum"
              />
            </div>
          </li>
        </ul>
        <ul class="more_ul">
          <li style="text-align: center;">
            <span class="more">
              {{ $store.state.isChinese ? '查看更多' : ' To view more' }}
            </span>
          </li>
        </ul>
        <div class="letter" :class="isFixed ? 'Fixed' : ''">
          <p
            :class="{ currentletterColor: currentletter == i }"
            v-for="(item, i) in letterArr"
            :key="i + 'll'"
            @click="toCurrentletter(i)"
          >
            {{ item }}
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import util from '@/assets/js/util.js';
export default {
  name: 'service',
  data() {
    return {
      radioGroup: '查看全部',
      colorNum: 0,
      currentletter: 0,
      letterArr: [
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
        'G',
        'H',
        'I',
        'J',
        'K',
        'L',
        'M',
        'N',
        'O',
        'P',
        'Q',
        'L',
        'M',
        'N',
        'O',
        'P',
        'Q',
        'R',
        'S',
        'T',
        'U',
        'V',
        'W',
        'X',
        'Y',
        'Z',
        '#',
      ],
      moduleId: 4,
      detailList: [],
      spinShow: false,
      navList: [],
      imgList: [
        {
          src: require('../assets/img/home/a1.png'),
          hoverSrc: require('../assets/img/home/a01.png'),
        },
        {
          src: require('../assets/img/home/a2.png'),
          hoverSrc: require('../assets/img/home/a02.png'),
        },
        {
          src: require('../assets/img/home/a3.png'),
          hoverSrc: require('../assets/img/home/a03.png'),
        },
        {
          src: require('../assets/img/home/a4.png'),
          hoverSrc: require('../assets/img/home/a04.png'),
        },
      ],

      value2: 0,
      imgNum: 0,
      currentfade: null,
      currentTab: null,
      isFixed: false,
    };
  },
  created() {
    this.getNavList();
    this.moduleId = this.$route.query.moduleId ? this.$route.query.moduleId : 4;
    if (this.$route.query.i) {
      this.toChangeTabs(this.$route.query.item, this.$route.query.i);
    } else {
    }

    this.getNaviListByModuleId();
  },
  watch: {},
  mounted() {
    window.addEventListener('scroll', this.showIcon);
    window.addEventListener('scroll', this.checkScroll);
  },

  methods: {
    // 页面滚动对应字母导航
    checkScroll() {
      this.letterArr.forEach((item) => {
        // 判断数据是否含有该字母
        this.detailList.forEach((li) => {
          // 如果有
          if (li.letter == item) {
            var cont1 = $(`.main_table .letter${item}`).offset().top - 100;
            var className = $(`.main_table .letter${item}`).attr('class');
            className = className.substr(className.length - 1, 1);
            var cont2 =
              $(`.main_table .letter${item}`).offset().top +
              $(`.main_table .letter${item}`).height() -
              100;
            var t =
              document.documentElement.scrollTop || document.body.scrollTop;
            if (t >= cont1 && t <= cont2) {
              this.letterArr.forEach((item, i) => {
                if (item == className) {
                  this.currentletter = i;
                }
              });
            } else {
            }
          }
        });
      });
    },
    // 收藏事件
    collection(i, m) {
      this.$Modal.warning({
        title: '提示',
        content: '请登录账号',
      });
      // 登录后可收藏
      // this.colorNum++;
      // this.detailList[i].list[m].iscolor = !this.detailList[i].list[m].iscolor;
    },
    showIcon() {
      if (document.documentElement.scrollTop > $('.letter').height()) {
        this.isFixed = true;
      } else {
        this.isFixed = false;
      }
    },
    openUrl(naviUrl) {
      window.open(naviUrl, '_blank');
    },
    toCurrentletter(i) {
      this.currentletter = i;
      this.detailList.forEach((item) => {
        if (item.letter == this.letterArr[i]) {
          $('body,html').animate(
            { scrollTop: $(`.letter${this.letterArr[i]}`).offset().top - 80 },
            1000,
          );
        }
      });
    },
    naviUrl(naviUrl) {
      window.open(naviUrl, '_blank');
    },
    toChangeTabs(item, v) {
      this.moduleId = item.id;
      this.navList.forEach((item, i) => {
        if (v != i) {
          this.navList[i].isChangeHeight = false;
        } else {
          this.navList[i].isChangeHeight = true;
        }
      });
      this.getNaviListByModuleId();
    },
    getNaviListByModuleId() {
      util
        .get(`/fta/fta/getNaviListByModuleId?moduleId=${this.moduleId}`)
        .then((response) => {
          if (response.code == 100) {
            let res = response.entity || [];
            res.forEach((item, i) => {
              item.list.forEach((li, m) => {
                li.letter = item.letter;
                li.isletter = false;
                li.iscolor = false;
                item.list[0].isletter = true;
              });
            });
            this.detailList = res;
          }
        })
        .catch((error) => {});
    },

    getNavList() {
      this.spinShow = true;
      util
        .get('/fta/fta/getModuleList')
        .then((response) => {
          if (response.code == 100) {
            this.navList = response.entity || [];
            this.imgList.forEach((item, m) => {
              this.navList[m].isChangeHeight = false;
              if (this.$route.query.i) {
                this.navList.forEach((item, i) => {
                  if (this.$route.query.i == i) {
                    this.navList[i].isChangeHeight = true;
                  }
                });
              } else {
                this.navList[m].isChangeHeight = false;
                this.navList[0].isChangeHeight = true;
              }

              for (var key in item) {
                this.navList[m][key] = item[key];
              }
            });
            this.spinShow = false;
          }
        })
        .catch((error) => {});
    },

    moreEnter(v) {
      if (this.navList[v].fade == v) {
        this.currentfade = v;
      }
      this.imgNum++;
    },
    moreLeave(v) {
      if (this.navList[v].fade == v) {
        this.currentfade = v;
      }
      this.imgNum++;
    },
  },
};
</script>

<style lang="less" scoped>
.service_contain {
  width: 100%;
  position: relative;
  margin-top: -100px;
  min-width: 1200px;

  .currentletterColor {
    color: #0092df !important;
    font-weight: bold;
  }
  .colorfont {
    color: #ffffff !important;
  }
  .colorLineHeight {
    background: linear-gradient(
      180deg,
      rgba(2, 146, 194, 0.9),
      rgba(3, 124, 183, 0.9) 100%
    );
    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
    color: #ffffff;
  }

  .bgImg {
    position: relative;
    width: 100%;
    height: 60%;
    .banner_title {
      position: absolute;
      z-index: 9999;
      right: 5%;
      bottom: 10%;
      transform: translate(-50%, -50%);
      color: #ffffff;
      font-size: 50px;
    }
    img {
      width: 100%;
      height: 100%;
    }
  }

  .carousel {
    min-width: 1200px;
    position: relative;
    width: 100%;
    height: 360px;
    display: flex;
    background: #ebebeb;
    .businessBox {
      display: inline-block;
      position: relative;
      height: 100%;
      width: 25%;
      border-right: 1px solid #e0e0e0;
      cursor: pointer;
      .businessBox:last-child {
        border-right: none;
      }

      .businessBox_content {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-around;
        padding: 50px;
        height: 100%;
        img {
          width: 90px;
          height: 90px;
        }
        .title {
          font-size: 30px;
          font-weight: normal;
          color: #333333;
          margin-top: 50px;
        }
        h4 {
          font-size: 16px;
          color: #666666;
          margin-top: 30px;
        }
        ul {
          position: relative;
          height: 0px;
          overflow: hidden;
          margin-top: 30px;
          li {
            width: 280px;
            height: 50px;
            border-bottom: 1px solid #fff;
            text-align: center;
            line-height: 50px;
            color: #ffffff;
          }
          li:first-child {
            background: #ffffff;
            opacity: 0.75;
            color: #0092df;
          }
          li:last-child {
            border-bottom: none;
          }
        }
        .more {
          margin-top: 60px;
          width: 140px !important;
          height: 50px !important;
          border: 1px solid #0092df !important;
          opacity: 1;
          border-radius: 80px;
          color: #0092df;
          line-height: 50px;
          text-align: center;
          cursor: pointer;
        }
      }
    }
    .businessBox:hover {
      background-color: #ddd;
    }
    .triangle {
      left: 50%;
      margin-left: -13px;
      bottom: -40px;

      position: absolute;
      box-sizing: border-box;
      width: 26px;
      height: 12px;
      border: 20px solid;
      border-color: rgba(3, 124, 183, 0.9) transparent transparent transparent;
    }
  }

  .companyList {
    width: 100%;
    background-color: #fff;
    padding-top: 50px;
    min-height: 1000px;

    .main_table {
      margin-bottom: 100px;
      padding-top: 30px;
      position: relative;
      width: 100%;
      padding: 0 5%;
      ul {
        // position: relative;
        width: 90%;
        li {
          height: 100px;
          line-height: 100px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          div {
            width: 100%;
            height: 100px;
            display: inline-block;
            font-size: 20px;
            font-weight: normal;
            color: #222222;
          }

          div:nth-child(1) {
            margin-right: none;
            white-space: none;
            text-overflow: none;
            padding-right: none;
          }

          .logo {
            display: inline-block;
            width: 40px;
            height: 40px;
            background: #0092df;
            border-radius: 50%;
            text-align: center;
            line-height: 40px;
            color: white;
          }
        }
        li:hover .bg_div {
          cursor: pointer;
          background-color: #f0f0f0;
          border-bottom: 1px solid #f0f0f0;
        }

        .more_ul {
          display: flex;
          align-items: center;
          justify-content: center;
        }
        .more_ul:hover {
          background-color: none;
        }
        .more {
          display: inline-block;
          margin: 50px auto;
          width: 140px;
          height: 50px;
          border: 1px solid #0092df !important;
          opacity: 1;
          border-radius: 4px;
          color: #0092df;
          line-height: 50px;
          text-align: center;
          cursor: pointer;
        }
      }
      .letter {
        position: absolute;
        top: -30px;
        right: 10%;
        font-size: 16px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        p {
          padding: 4px 3px;
          line-height: 20px;
          color: #666666;
          cursor: pointer;
        }
      }
      .Fixed {
        position: fixed;
        top: 80px;
        right: 10%;
      }
    }

    h2 {
      font-size: 20px;
      span {
        color: #ccc;
        font-size: 14px;
        font-weight: normal;
        margin-left: 10px;
      }
    }
  }
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值