Небольшие программы от ручного встраивания до автоматического встраивания

Апплет WeChat

предисловие

Из-за сильной закрытости небольших программ будет сложно добиться гибкого сбора данных, как в веб-приложениях. В настоящее время SDK для захоронения с открытым исходным кодом обычно использует метод ручного захоронения.Этот метод имеет сильный тип вторжения и высокую стоимость разработки.Чтобы решить эту проблему, эта статья опубликована.

Похоронен вручную

Взяв в качестве примера SDK Tencent Mobile Analytics, если вы хотите записать информацию о скрытых точках, вам нужно всего лишь вставить код.

// 例如,记录搜索行为
search(keyword) {
   if (keyword) {
       ...业务代码
   }
   // 埋点代码
   mta.Event.stat("ico_search", {"query":keyword});
}

Пример кода выглядит относительно лаконично, но данные, которые нужно собрать, зачастую не единичны.Влияет на опыт чтения кода,а такжеСкрытый код разбросан по разным местам, что неудобно в управлении.

Поскольку точки захоронения должны быть вставлены в функцию вручную, иногда для получения информации о щелчке элемента на странице создаются своего рода точки захоронения, называемые точками захоронения, не связанными с бизнесом.Код будет серьезно загрязнен.

// wxml
<view bindtap="track">这只是一个展示view</view>

//js 
track() {
  mta.Event.stat("eleClick", {"name":xxxxx});
}

Кроме того, поскольку PM будет часто корректировать информацию о скрытых точках, иЗакапывание - утомительная и скучная работа, В соответствии с принципом «Не повторяйся», ручное захоронение недопустимо.

Подводя итог вышесказанному, ручное встраивание имеет следующие проблемы.

  1. Влияет на опыт чтения кода
  2. Скрытый код разбросан по разным местам, что неудобно в управлении
  3. код будет загрязнен
  4. Закапывание - утомительная и скучная работа

автоматическое захоронение

1. Отслеживайте, нажимается ли элемент через всплывающее окно событий

Апплет не предоставляет метод мониторинга событий Dom, но мы можем отслеживать его с помощью всплытия событий, связывать событие перехвата на самом внешнем уровне wxml, чтобы получить координаты элемента, на который нажали, и определить, являются ли координаты элемента, на который нажали, и цель мониторинга пересекается, чтобы вызвать запись.

Метод определения того, пересекает ли позиция клика элемент:

Ниже приведен код реализации

// 小程序监听页面点击,用户的点击行为都会执行elementTracker方法
<view catchtap='elementTracker'>
  <view class='buy-now'>
     <button bindtap='buy'>立即购票</button>
  </view>
</view>

// js 
elementTracker(clickInfo) {
  // 需要记录元素的className
  const trackElementName = '.more';
  // 通过元素坐标信息与点击坐标信息,判断是否被点击
  this.getBoundingClientRect(trackElementName).then((res) => {
    res.boundingClientRect.forEach((item) => {
      const isHit = this.isClickTrackArea(clickInfo, item, res.scrollOffset);
      console.log(isHit, 'isHit')
    });
  });
},
/**
 * 判断点击是否落在目标元素
 * @param {Object} clickInfo 用户点击坐标
 * @param {Object} boundingClientRect 目标元素信息
 * @param {Object} scrollOffset 页面位置信息
 * @returns {Boolean} 是否被点击
 */
isClickTrackArea(clickInfo, boundingClientRect, scrollOffset) {
  if (!boundingClientRect) return false;
  const { x, y } = clickInfo.detail; // 点击的x y坐标
  const { left, right, top, height } = boundingClientRect;
  const { scrollTop } = scrollOffset;
  if (left < x && x < right && scrollTop + top < y && y < scrollTop + top + height) {
    return true;
  }
  return false;
},
/**
 * 获取页面元素信息
 * @param {String} element 元素class或者id
 * @returns {Promise}
 */
getBoundingClientRect (element) {
  return new Promise((reslove) => {
    const query = wx.createSelectorQuery();
    query.selectAll(element).boundingClientRect();
    query.selectViewport().scrollOffset();
    query.exec(res => reslove({ boundingClientRect: res[0], scrollOffset: res[1] }));
  });
}

2. Расширьте метод Page

Поскольку метод elementTracker должен быть определен в Page для вызова wxml, было бы слишком громоздко вручную писать каждую страницу. Автоматическое расширение может быть достигнуто путем перезаписи страницы. Код выглядит следующим образом.

// 记录原Page方法
const originPage = Page;
// 重写Page方法
Page = (page) => {
  // 给page对象注入三个方法
  page.elementTracker = function() {}
  page.methodTracker = function() {}
  page.isClickTrackArea = function() {}
  return originPage(page);
};

3. Точки захоронения для функций страницы

В некоторых сценариях, в дополнение к щелчку и скрытию элементов страницы, нам также необходимо скрыть функции страницы. Например, когда пользователь тянет вниз, чтобы обновить, мы можем обернуть исходный метод и вставить скрывающий код. Решение аналогичное. до третьего пункта.

const originPage = Page;
// 重写Page方法
Page = (page) => {
  // 给onShow方法插入埋点
  const originMethod = page['onShow'];
  page['onShow'] = function() {
    report() // 记录埋点
    return originMethod();
  }
  return originPage(page);
};

4. Установите скрытую точку через таблицу конфигурации.

Выше описан способ сокрытия элементов и функций страницы.Давайте поговорим о том, как управлять информацией о точке сокрытия для решения проблемы вторжения в код.Информация о точке сокрытия может быть объявлена ​​в виде таблицы конфигурации, а также может быть в дальнейшем динамически настраивается, а конфигурация завершается на стороне сервера, доставляется клиенту.

const tracks = {
  path: 'pages/film/detail',
  elementTracks: [
    {
      element: '.buy-now',  // 声明需要监听的元素
      dataKeys: ['film.filmId'], // 声明需要获取Data下的film对象下的filmId字段
    },
    methodTracks: [
    {
      method: 'toBannerDetail', // 声明需要监听的函数
      dataKeys: ['imgUrls'], // 声明需要获取Data下的imgUrls数据
    },
  ],
  ]
};

наконец

Полный код упакован в SDK, который можно быстро интегрировать в проектгитхаб-адрес