小程序scroll-view左右滑动联动效果

效果图
在这里插入图片描述

<view class='cont-pro'>
	<!-- 左侧列表 -->
	<scroll-view scroll-y='true' scroll-with-animation="true" style="width:25%;">
		<view class='pro_left'>
			<view wx:for="{{serviceTypes}}" wx:key='index' class="pro_title {{index==currentLeft?'select':''}}" bindtap='proItemTap' data-pos='{{index}}'>{{item.type}}</view>
		</view>
	</scroll-view>
	<!-- 右侧列表 -->
	<scroll-view scroll-y='true' style="width:75%;" scroll-with-animation="true" scroll-into-view="{{selectId}}" bindscroll="scroll" scroll-top="{{scrollTop}}">
		<view class='pro_right'>
			<view id='{{"item"+index}}' class='pro_box' wx:for="{{serviceTypes}}" wx:for-index="index" wx:key='index' wx:for-item="item">
				<view class="item_title">{{item.type}}</view>
				<view class='pro_item' wx:for="{{item.services}}" wx:for-index="idx" wx:key='idx' wx:for-item="itemName">
					<image class='pro_img' src='{{itemName.img}}'></image>
					<view class='pro_text'>
						<view class='item_name'>{{itemName.name}}</view>
					</view>
				</view>
			</view>
		</view>
	</scroll-view>
</view>

var app = getApp();
Page({
  heightArr: [],
  distance: 0,
  data: {
    currentLeft: 0, //左侧选中的下标
    selectId: "item0",  //当前显示的元素id
    scrollTop: 0, //到顶部的距离
    serviceTypes: [
      {
        type:"标签1",
        services:[
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          }
        ]
      },
      {
        type:"标签2",
        services:[
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",

          }
        ]
      },
      {
        type:"标签3",
        services:[
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          }
        ]
      },
      {
        type:"标签4",
        services:[
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          }
        ]
      },
      {
        type:"标签5",
        services:[
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          },
          {
            img:"https://sucai.suoluomei.cn/sucai_zs/images/2020/07/09/a46a0c7da07765be4454817b8c6fc6a2.jpg",
            name:"商品标题",
          }
        ]
      }
    ], //项目列表数据
    staffList: [],
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    this.selectHeight();
  },
  // 左侧标签选择操作锚点定位
  proItemTap(e) {
    this.setData({
      currentLeft: e.currentTarget.dataset.pos,
      selectId: "item" + e.currentTarget.dataset.pos
    })
  },

  //计算右侧每一个分类的高度,在数据请求成功后请求即可
  selectHeight() {
    let that = this;
    this.heightArr = [];
    let h = 0;
    const query = wx.createSelectorQuery();
    query.selectAll('.pro_box').boundingClientRect()
    query.exec(function(res) {
      res[0].forEach((item) => {
        console.log(item,res[0])
        h += item.height;
        that.heightArr.push(h);
      })
      console.log(that.heightArr);
    })
  },
  //监听scroll-view的滚动事件
  scroll(event) {
    if (this.heightArr.length == 0) {
      return;
    }
    let scrollTop = event.detail.scrollTop;
    let current = this.data.currentLeft;
    if (scrollTop >= this.distance) { 
      //页面向上滑动
      //如果右侧当前可视区域最底部到顶部的距离 超过 当前列表选中项距顶部的高度(且没有下标越界),则更新左侧选中项
      if (current + 1 < this.heightArr.length && scrollTop >= this.heightArr[current]) {
        this.setData({
          currentLeft: current + 1
        })
      }
    } else { 
      //页面向下滑动
      //如果右侧当前可视区域最顶部到顶部的距离 小于 当前列表选中的项距顶部的高度,则更新左侧选中项
      if (current - 1 >= 0 && scrollTop < this.heightArr[current - 1]) {
        this.setData({
          currentLeft: current - 1
        })
      }
    }
    //更新到顶部的距离
    this.distance = scrollTop;
  }
})

.cont-pro {
  height: 100%;
  display: flex;
  background-color: #fff;
  flex-direction: row;
}

.pro_left {
  width: 100%;
  background-color: #fff;
  height: 100vh;
  display: flex;
  flex-direction: column;
  border-right: 1rpx solid#eee;
}

.pro_title {
  width: 100%;
  height: 150rpx;
  line-height: 150rpx;
  text-align: center;
  border-bottom: 1rpx solid #eee;
}

.select {
  width: 100%;
  height: 150rpx;
  line-height: 150rpx;
  text-align: center;
  color: #fff;
  background: #f08d31;
}

.pro_right {
  width: 100%;
  background-color: #fff;
  height: 100vh;
}

.item_title {
  width: 100%;
  height: 50px;
  line-height: 100rpx;
  padding: 0 30rpx;
  box-sizing: border-box;
}

.item_name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
  word-break: break-all;
}

.pro_item {
  width: 100%;
  display: flex;
  padding: 30rpx;
  box-sizing: border-box;
}

.pro_img {
  width: 160rpx;
  height: 160rpx;
  flex-basis: 160rpx;
  flex-shrink: 0;
  border-radius: 4rpx;
  margin-right: 30rpx;
  background-color: #f5f5f5;
}

.pro_text {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

在uni-app中,`<scroll-view>` 组件用于创建滚动视图容器,用户可以在其中滑动查看内容。当想要实现在 `<scroll-view>` 中左右两侧的内容联动时,通常需要利用到事件监听、数据绑定以及一些自定义的计算逻辑。 ### 实现原理 1. **事件监听**:首先,在主 `<scroll-view>` 内部设置滚动事件,如 `bindscroll` 或者直接使用 `@scroll`,以便获取滚动位置信息。 ```javascript <scroll-view scroll-x="true" bindscroll="onScroll"> <!-- 内容区域 --> </scroll-view> ``` 其中 `scroll-x="true"` 表示水平滚动。 JavaScript 部分: ```javascript export default { data() { return { scrollLeft: 0 // 初始化滚动位置为0 }; }, methods: { onScroll(e) { this.scrollLeft = e.detail.scrollX; // 获取当前滚动位置 } } }; ``` 2. **数据绑定**:基于获取到的滚动位置,可以将这个值应用于另一个 `<scroll-view>` 的 `scroll-left` 属性上,以此实现联动效果。 ```html <view class="container"> <!-- 左侧联动滚动区 --> <scroll-view scroll-x "true" :scroll-left="scrollLeft"> <!-- 左侧内容 --> </scroll-view> <!-- 右侧内容 --> <scroll-view scroll-y="true"> <!-- 右侧内容 --> </scroll-view> </view> ``` 3. **计算属性/方法**:如果需要更复杂的效果,比如根据滚动的位置调整右侧内容的高度或其他动态属性,可以使用 Vue.js 的计算属性或方法来实现。 ### 相关问题: 1. 在 `uni-app` 中如何控制滚动视图的动画效果? 2. 如何在 `uni-app` 中实现垂直滚动视图的自动跟随? 3. `uni-app` 中如何优化滚动性能避免卡顿现象?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值