微信小程序 关注页滚动条滚动视频自动播放功能

最近公司的小程序需要在关注页面加一个滚动页面自动播放视频功能,研究出来之后,在此写个博客记录一下。
自己是技术小白,写的不好bug多,请轻喷!!!!
这篇博客只是给自己记录一下。有更好的方法也欢迎讨论 ~ ~

关注页滚动视频播放

实现思路

  1. 在页面初加载时,拿到所有视频的top值,且如果第一条帖子是视频的话就播放。因为小程序没有DOM结构,所以要借助wx.createSelectorQuery();来拿到top值,具体代码后面会贴出。
  2. 因为视频有横屏和竖屏拍摄,高度不一,所以需要拿到横屏与竖屏的宽度值以便之后做判断,我这里的视频宽高是从后端返回的数据
  3. 计算出横屏视频上下滑动开始播放区域和竖屏视频上下滑动开始播放区域
  4. 利用滚动监听onPagescroll(),当上 \ 下滑到视频播放区域时视频播放,目前还没做视频播放暂停,后期测试阶段会再进一步优化。
  5. 下面贴出代码
在要获取高度的视频上加个id,因为视频未播放时一般是放个视频截图在那占位,所以要获取图片的高度,并且要获取到scroll-view的高度,以便之后计算差值。
<!-- 视频设为自动播放,当 selectPlayid 与 item.id 相等时播放,视频截图隐藏,截图由后端生成 -->
<block wx:if="{{selectPlayid==item.id}}">
    <video class="vedioitem vediotext" catchtap="vedioClick" bindended='clocechuang' data-item='{{item}}' id="vedio{{item.id}}" src="{{item.vedio}}" style="width:{{item.vedio_widths}}px;height:{{item.vedio_heights}}px" controls autoplay></video>
</block>

<scroll-view scroll-y id='guanzhuscrollid' class='tiezitext' bindscroll="scrolls" style="width:100%;white-space: nowrap;padding-top:106px">
<image class='tzplayerimg' id='tiezibody{{item.id}}' src='{{item.avatar}}'></image>
初加载时执行函数getimgTop()
 // getviewHeight: function (id) {
  //   var query = wx.createSelectorQuery();
  //   //选择id
  //   query.select('#tiezibody' + id).boundingClientRect()
  //   query.exec(function (res) {
  //     //res就是 所有标签为mjltest的元素的信息 的数组
  //     // console.log(res);
  //     //取高度(213px)
  //     // console.log(res[0].height);
  //   })
  // },


 getimgTop: function () {
    var that = this;
    // 创建节点选择器
    var query = wx.createSelectorQuery();
    
    var viewIndex = this.data.viewIndex;
    var viewId = this.data.articles[viewIndex].id;
    let articles = this.data.articles;
    var arr = [], brr = []

    // 拿到所有视频的id值
    for (let i = 0; i < articles.length; i++) {
      arr.push(articles[i].id)
    }
    this.setData({
      imgidlist: arr
    })

    // 拿到所有视频的DOM值
    for (let i = 0; i < arr.length; i++) {
    // 选择id
      query.select('#tiezibody' + arr[i]).boundingClientRect()
      query.exec(function (res) {
      // res里有宽高top等字段
        brr = res
      })
    }

    // 判断第一个帖子是否是视频,是视频就播放
    query.select('#tiezibody' + viewId).boundingClientRect()
    query.exec(function (res) {
      that.setData({
        toplist: res,
        selectPlayid: articles[0].id
      })
      that.gettopList();
    })

    // 拿到scroll-view的高度
    query.select('#guanzhuscrollid').boundingClientRect()
    query.exec(function (res) {
      let len = res.length - 1;
      that.setData({
        scrollHeight: parseInt(res[len].height)
      })
    })

    // console.log(articles);
  },

计算横 \ 竖视频上下滑动时播放视频的区域
 gettopList: function () {
    // 所有dom值
    var toplist = this.data.toplist;
    // 所有的帖子数据,包含视频宽高
    var articles = this.data.articles;
    var brr = [];
    var arr = [];
    var crr = [];

    // 拿到所有视频的top值
    for (let i = 0; i < toplist.length; i++) {
      brr.push(toplist[i].top);
    }
    var imgidlist = this.data.imgidlist;

    // 将视频的top值、id、width、下滑开始播放区域高度start end、上滑开始播放区域高度start_1 end_1 存入数组arr
    for (let j = 0; j < imgidlist.length; j++) {
      if (this.data.articles[j].vedio != '' && this.data.articles[j].vedio) {
        arr[j] = {};
        arr[j].top = brr[j];
        arr[j].id = imgidlist[j];
        arr[j].width = articles[j].vedio_widths;
        // 横屏
        if(arr[j].width > 300){
          arr[j].start = parseInt(arr[j].top - 585);
          arr[j].end = parseInt(arr[j].top -195);
          arr[j].start_1 = parseInt(arr[j].top + 28);
          arr[j].end_1 = parseInt(arr[j].top - 385);
        }else{ // 竖屏
          arr[j].start = parseInt(arr[j].top - 490);
          arr[j].end = parseInt(arr[j].top + 10 );
          arr[j].start_1 = parseInt(arr[j].top + 140);
          arr[j].end_1 = parseInt(arr[j].top - 208);
        }
      }
    }
    // 过滤掉没有视频的帖子
    for (let v = 0; v < arr.length; v++) {
      if (arr[v] != '' && arr[v]) {
        crr.push(arr[v]);
      }
    }
    console.log(crr)
    this.setData({
      tops: crr,
    })

  },
滚动监听 ———— 因为里面有多个判断和循环,所以我在这做了节流
 // 滚动监听 + 节流 
  onPageScroll: toolUtil.throttle(function(e) {
    var tops = this.data.tops;
    // console.log(e[0].scrollTop);
    var _this = this;
    //当滚动的top值最大或最小时,为什么要做这一步是因为在手机实测小程序的时候会发生滚动条回弹,所以为了处理回弹,设置默认最大最小值
    if (e[0].scrollTop <= 0) {
      e[0].scrollTop = 0;
    } else if (e[0].scrollTop > this.data.scrollHeight) {
      e[0].scrollTop = this.data.scrollHeight;
    }
    //判断浏览器滚动条上下滚动
    if (e[0].scrollTop > this.data.scrollTop || e[0].scrollTop == this.data.scrollHeight) {
      //向下滚动
      for (let i = 0; i < tops.length; i++) {
        if (e[0].scrollTop >= tops[i].start && e[0].scrollTop <= tops[i].end){
          this.setData({
            selectPlayid: tops[i].id
          })
          // console.log('向下滚动tops['+i+']',tops[i].top);
        }
      }

    } else {
      //向上滚动
      for (let i = 0; i < tops.length; i++) {
        if (e[0].scrollTop <= tops[i].start_1 && e[0].scrollTop >= tops[i].end_1){
          this.setData({
            selectPlayid: tops[i].id
          })
          // console.log('向上滚动tops[' + i + ']', tops[i].start_1);
        }
      }
    }
    //给scrollTop重新赋值
    setTimeout(function () {
      _this.setData({
        scrollTop: e[0].scrollTop
      })
    }, 0)
  }),
节流函数我封装在了公用js中
/*函数节流*/
exports.throttle = function (fn, interval) {
  var enterTime = 0;//触发的时间
  var gapTime = interval || 300;//间隔时间,如果interval不传,则默认300ms
  return function () {
    var context = this;
    var backTime = new Date();//第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(context, arguments);
      enterTime = backTime;//赋值给第一次触发的时间,这样就保存了第二次触发的时间
    }
  };
}

关于小程序节流和防抖有一个大佬的博客写的很清楚,大家对这方面有疑问的可以看看
https://www.cnblogs.com/zjjDaily/p/10840276.html

补充!!!!
scroll-view里面不能包含video组件的!!这是个大坑,如果使用scroll-view在苹果机上退出全屏会重新回到顶部

### 微信小程序实现纵向滚动条 要在微信小程序中实现纵向滚动条,可以通过 `<scroll-view>` 组件并设置其 `scroll-y` 属性为 `true` 来完成。以下是具体的代码示例以及 CSS 样式的配置方法。 #### 示例代码 ```html <view class="container"> <scroll-view scroll-y="{{true}}" style="height: 300px;"> <!-- 这里放置需要滚动的内容 --> <view wx:for="{{items}}" wx:key="index" class="item">{{item}}</view> </scroll-view> </view> ``` #### CSS 样式 为了隐藏滚动条的同时保持功能正常,在 `.wxss` 文件中可以添加如下样式: ```css /* 隐藏滚动条 */ ::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; -webkit-appearance: none; background: transparent; color: transparent; } .container { width: 100%; overflow: hidden; /* 确保容器不会溢出 */ } .item { padding: 20rpx; border-bottom: 1px solid #ccc; } ``` 上述代码通过设置 `display: none` 和其他相关属性来强制隐藏滚动条[^1]。同时,`overflow: hidden` 能够进一步确保容器内的内容不会超出边界[^4]。 #### 数据绑定与动态高度调整 如果希望根据实际数据量自动调整滚动区域的高度,则可以在面逻辑文件中定义动态计算逻辑。例如: ```javascript Page({ data: { items: Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`), // 模拟大量数据 }, }); ``` 此部分实现了生成模拟列表项的功能,并将其绑定到 WXML 中的 `{{items}}` 上[^3]。 --- ### 注意事项 - **iOS 兼容性**:在 iOS 设备上,默认情况下可能难以完全隐藏滚动条。因此建议严格按照提供的样式规则操作以达到最佳效果。 - **性能优化**:当处理非常庞大的数据集时,考虑采用虚拟列表技术减少渲染压力。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值