zl程序教程

您现在的位置是:首页 >  工具

当前栏目

【前端探索】微信小程序跳转的探索——开放标签为什么存在?

微信程序前端 探索 为什么 标签 存在 开放
2023-06-13 09:18:47 时间

【2022.01.25修正】现在URL Scheme支持微信内跳转了,可以不用在微信内特殊处理成开放标签。

1、有哪些途径可以拉起小程序?

微信开放标签

小程序链接URL Scheme

小程序链接URL Link

APP拉起小程序

2、各种途径的示例

URL Scheme示例

URL Link和微信开放标签示例

查看第二个示例和官方文档,可以看到,URL Link就是在微信外用URL Scheme,在微信内用开放标签。且微信内不会直接拉起小程序,需要手动点一下拉起按钮触发拉起小程序

3、各种途径的对比

途径

适用渠道

是否支持开发版,体验版小程序

接入步骤

微信开放标签

微信内网页,只能手动点击跳转。

只支持正式版

引入SDK,调用接口

URL Scheme

微信外网页

只支持正式版

服务端接口或在小程序管理后台

URL Link

全部网页,其实是前两种途径的结合

只支持正式版

服务端接口

APP拉起小程序

APP,可以给APP的内嵌提供跳转接口

都支持

引入SDK,调用接口

*经过测试,scheme在iOS和部分安卓机上,也可以在微信内拉起小程序,但是在部分安卓机上,比如小米11,是无效的。我们无法只用scheme做到一通百通。

4、微信开放标签

用过微信开放标签的开发,都会知道,微信开放标签提供的接口,很难用,他提供的是一个html标签,还要在标签里面插入自定义的html元素。

其实提供一个js方法,一调用这个方法,直接拉起小程序,不就很方便么,或者在微信内也支持用scheme拉起,那开发者不是美滋滋,但是微信偏不。

<wx-open-launch-weapp
 id="launch-btn"
 username="gh_xxxxxxxx"
 path="pages/home/index?user=123&amp;action=abc"
>
  <script type="text/wxtag-template">
    <style>.btn { padding: 12px }</style>
             打开小程序
     </script>
</wx-open-launch-weapp>
<script>
   var btn = document.getElementById('launch-btn');
   btn.addEventListener('launch', function (e) {
    console.log('success');
   });
   btn.addEventListener('error', function (e) {
    console.log('fail', e.detail);
   });
</script>

5、微信内的特殊处理

微信开放标签看起来是为了某些特殊目的设计出来的跳转小程序途径。

结合微信开发者论坛中一些提问,有些开发者妄图通过在开放标签上模拟click事件,实现对微信内拉起小程序的封装,或者直接一进入网页就拉起小程序,但是都以失败告终,可想而知,微信不想让用户在“微信内”不通过点击,就直接拉起小程序

6、看看代码

为了实现这一目的,开放标签做了怎么样的努力呢?

为了一探究竟,我们需要在微信内调试一下开放标签,具体操作参考这篇文章

x5浏览器调试微信内页面

打开已经接入了开放标签的H5页面,我们可以看到开放标签被渲染成一个iframe,iframe的body中,又插入了我们传进去写在wxtag-template标签里面的html。

原来是iframe,这也就解释了为什么我们在wxtag-template标签里,用外部的样式会不生效了。开放标签生效后,我们的点击操作,其实点击的是iframe里面的html,这也解决了我们接入开放标签时候的大多数问题:

(1)点击不生效->看下ifame里面的html的点击区域是否正常

(2)样式不生效->看下是否在iframe里面的html用了外部的样式,或者iframe内部和外部的html相互遮挡。

7、封装一下

明白了开放标签做了什么,我们可以对开放标签做一下封装,原来的开放标签实在太难用了。

既然开放标签用上了iframe来阻止我们通过js方法直接拉起小程序,直接封装成一个拉起小程序的方法是不太现实了,即使实现了,也会面临开放标签突然改一下iframe里面的实现使得我们的封装失效的风险。

那我们还是乖乖的用点击按钮来拉起小程序。

我们可以封装的方法是:在我们想触发拉起小程序的按钮上,覆盖上这个开放标签,保证开放标签的iframe以及里面的html,和覆盖的按钮尺寸一致,且样式是透明的。

这样封装我们就不需要关系开放标签和里面html的样式,也不存在点击区域不一致导致无法拉起小程序的问题。

/**
 * 覆盖一个开放标签到传入的options.el元素上,点击可以跳转到对应小程序
 * @exports wxOpenLaunchWeapp
 * @param {Object} options {el:dom,appid:id,url:path} 参数:元素、小程序原始ID、小程序路径
 */

const wxOpenLaunchWeapp = function (options) {
 // configWx,完成微信鉴权,这个有个小坑,开放标签必须随便传一个jsApiList,即使用不到也要传,否则安卓拉不起小程序
 configWx(['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareQZone'], ['wx-open-launch-weapp']).then((wx) => {
  console.log(wx);
  const btn = options.el; // 获取元素
  const script = document.createElement('script'); // 创建script内容插槽
  script.type = 'text/wxtag-template';
  // 插槽里面插入透明且和外部元素大小一致的a标签
  const defaultHtml = `<a style='width:${options.el.clientWidth}px;height:${options.el.clientHeight}px;display:block;color: transparent;'>default buttom</a>`;
  script.text = defaultHtml;
  // 开放标签的尺寸也和外部元素一致,且为绝对布局
  const html = `<wx-open-launch-weapp
          id="launch-btn"
          style="width:${options.el.clientWidth}px;
          height:${options.el.clientHeight}px;
          display:block;
          position: absolute;
          z-index: 20;" 
          username="${options.appid}"
          path="${options.url}">${script.outerHTML}</wx-open-launch-weapp>`;
  const btnParent = btn.parentElement;
  btnParent.innerHTML = html + btnParent.innerHTML; // html字符串赋值
  const launchBtn = document.getElementById('launch-btn');
  launchBtn.addEventListener('ready', (e) => {
     console.log('ready', e);
  });
  launchBtn.addEventListener('launch', (e) => {
     console.log('success', e);
  });
  launchBtn.addEventListener('error', (e) => {
     console.log('fail', e.detail);
  });
 });
};

我们在使用的时候,只需要传入按钮元素、小程序原始ID和路径

initWeixinJumpMiniProgram(buttonDom) {
   const options = {
      el: buttonDom,
      appid: this.water.miniProgramSourceId,
      url: this.water.miniProgramJumpUrl,
   };
   wxOpenLaunchWeapp(options);
}

结合URL Scheme,我们加一层判断,用户在微信外用scheme拉起小程序,在微信内用微信开放标签。这就可以做到,用户在微信内外都是一样的体验,没有了URL Link的中转页,用户体验会好很多。