前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在微信小程序中实现商品曝光的统计

在微信小程序中实现商品曝光的统计

作者头像
用户1687375
发布2019-07-30 15:50:40
3.2K0
发布2019-07-30 15:50:40
举报
文章被收录于专栏:较真的前端较真的前端

本文首发于知乎,点击文章底部的“阅读原文”来访问原文地址

什么"商品曝光率"?

在电商运营的工作中,运营人员需要关心很多数字,除了简单的PV和UV外,还有商品曝光量、商品浏览量、加入购物车、支付量,基于这些数字可以构建漏斗模型,帮助优化各个环节的转化,如下图。

商品转化漏斗

商品曝光量其实就是商品被用户看到的次数,换做程序员能听懂的话就是——商品组件滚入屏幕内,如下图

如何统计商品曝光量

想要统计曝光量,其实只需要做两件事:

  • 判断商品组件是否在屏幕(Viewport)内部
  • 如果在屏幕内部,则将包含商品信息的曝光事件(Event)发送到日志服务器

在原生App和web中都有相应成熟的解决方案。但是今天要讨论的是微信小程序中的统计方式。

在web中统计曝光的话,可以监听滚动事件,然后根据元素的offset().top 和 body元素的scrollTop进行计算元素相对于Viewport的位置,从而判断当前页面中有哪些商品组件在屏幕内。但是微信小程序与web不同的是,他并没有dom,也就无法拿到你想要的元素。所以必须另寻其他解决方案。

微信小程序的IntersectionObserver接口

官方文档的解释是

IntersectionObserver对象,用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见。

这个解释听上去刚好满足了"商品曝光量"统计的需求,但是事情并没那么顺利。

先看看官方示例:

代码语言:javascript
复制
Page({
  onLoad: function(){
    wx.createIntersectionObserver()
      .relativeToViewport({bottom: 100})
      .observe('.target-class', (res) => {
        res.intersectionRatio // 相交区域占目标节点的布局区域的比例
        res.intersectionRect // 相交区域
        res.intersectionRect.left // 相交区域的左边界坐标
        res.intersectionRect.top // 相交区域的上边界坐标
        res.intersectionRect.width // 相交区域的宽度
        res.intersectionRect.height // 相交区域的高度
      })
  }
})

顺着这个思路,我们似乎只需要做两\件事就接近任务完成了:

  • 给"商品组件"定义个className用与替换上面代码.observe()方法中的第一个参数,以便作为"被观察"节点。比如我们可以为"商品组件"追加一个.product-exp的class
  • 在"商品组件"的节点上追加dataset,用于将商品信息事先埋好,以便observe()的第二个参数——回调中可以拿到,最终发送给日志服务器

商品组件伪代码示意图

如果一切顺利,每个具有.product-exp的"商品组件"滚入屏幕内时,observe()方法的回调将被调用。可是。。。。事与愿违

最终的实验结果是,只有第一个.product-exp节点滚入屏幕内时,才会触发observe()的回调,也就是说在.observer()方法中的"选择器"并不是我们熟悉的Web中的选择器,无论是什么选择器,一次只能选择一个元素。

换用id选择器

之所以想用class选择器,是因为我们想用一个IntersectionObserver对象解决所有"商品组件"的问题。我们可以换个思路,为每个"商品组件"创建一个唯一的id(最好是随机数),然后将id选择器传入.observer()方法。

以上是示例伪代码

何时创建IntersectionObserver对象

如果你使用原生小程序进行开发,应该在组件内部的ready生命周期内创建IntersectionObserver对象,组件内部的创建方法有些不同。在自定义组件或包含自定义组件的页面中,应使用 `this.createIntersectionObserver([options])` 来代替。

但是如果使用的是Mpvue框架进行开发的话,就会有点小麻烦。

在Mpvue中的特殊处理

Mpvue中的组件并没有ready生命周期

原因是Mpvue通过模板<template>来实现组件,这个在绝大情况下是没有问题的,但是在使用IntersectionObserver对象的前提条件是选择器对应的节点已经存在,即组件已经挂载

Mpvue中就会遇到几个问题:

  • 无法知道"组件"是否已经挂载
  • 如果在组件挂载之前创建IntersectionObserver对应的话,只会有警告并没有报错

image

  • IntersectionObserver对象在未找到节点时,返回值也并没有不同。最终结果就是在代码中,你无法获得失败的状态,也就无法进行重试。失败状态被IntersectionObserver吞掉了

需要换个思路。

微信小程序还提供了SelectorQuery对象,类似浏览器中的document.querySelector。用法有所不同,如下:

代码语言:javascript
复制
// 创建SelectorQuery对象
const query = wx.createSelectorQuery()
// 选择节点
const nodeRef = query.select('#the-id')
// 添加节点的布局位置的查询请求。
nodeRef.boundingClientRect()
// 执行查询
query.exec(function(res){
  // 回调中可以拿到相关查询信息
})

SelectorQuery.exec()的回调中,我们可以判断当前节点是否存在。

当节点存在时,回调中返回的数组第一位就是我们要的节点。

当节点不存在时,回调中返回的数组第一位是null

于是可以基于SelectorQuery设定一套IntersectionObserver的重试机制,即当节点不存在时,各一定时间(如200ms)进行一次重试,这样就会保证IntersectionObserver一定可以找到"商品组件"了。

总结

IntersectionObserver可以用来检查某个节点是否已经滚入屏幕,但是如果节点不存在时,IntersectionObserver会吞掉失败状态,所以在此之前利用SelectorQuery对象来确定节点是否已经存在。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 较真的前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么"商品曝光率"?
  • 如何统计商品曝光量
  • 微信小程序的IntersectionObserver接口
    • 换用id选择器
      • 何时创建IntersectionObserver对象
        • 在Mpvue中的特殊处理
        • 总结
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档