2018-06-12

2018-06-12

[18-06-29]获取h5长按识别小程序码进入小程序事件
[18-06-28]微信小程序没法通过wx.navigateBack主动关闭小程序
[18-06-22]微信h5页面, 如果阻止了touch事件的默认动作, 会导致微信不会出现长按识别二维码菜单
[18-06-19]原生js如何删除一个元素上所有的EventListener
[18-06-12]使用webpack动态导入功能最终生成多个bundle时,如何指定异步bundle的url

[18-06-29]获取h5长按识别小程序码进入小程序事件

业务场景是这样的, 用户长按图片 -> 微信出现识别二维码菜单 -> 识别二维码并打开小程序, 目前并没有办法获知用户是否点击识别二维码, 也无法获知识别二维码的菜单出现的时机, 除去一些后端的方案(如websocket)之外, 前端也是可以通过hack来模拟的(但hack是不完美的, 有缺陷的实现方案, 我更倾向说服产品经理放弃这样的交互)

{
  // vue config
  // ...
  onTouchStart(e) {
    window.onblur = null
    clearTimeout(this.cancalOnblur || '')
    // 0.1s即识别认为是长按, 因为时间设得较短, 因为有的手机微信在很短的时间弹出菜单了, 此处为缺陷1
    timeOutEvent = setTimeout(this.onLongTapSuccess, 100)
  },
  onTouchMove() {
    clearTimeout(timeOutEvent)
    timeOutEvent = 0
  },
  onLongTapSuccess() {
    const self = this
    window.onblur = function () {
      // 进入小程序时, window触发失焦
      // 微信进入后台也会触发window失焦, 可能还有其他情况会触发window失焦, 但还没有发现
      // 此为缺陷2
    }
    // 如果5秒内没有失去焦点, 则取消失焦事件
    // 这里的时长怎么断定? 用户就是有可能5s内都没有点击菜单, 然后5秒后点击进去小程序了
    // 此为缺陷3
    this.cancalOnblur = setTimeout(() => {
      window.onblur = null
    }, 5000)
  }
}
[18-06-28]微信小程序没法通过wx.navigateBack主动关闭小程序

wx.navigateBack可以用来返回上一页面或多级页面, 在之前的版本中, 当wx.navigateBack的参数大于页面栈里的值时, 是可以直接关闭小程序的, 但这个hack不知道在哪个版本中修复了, 现在已经不能通过wx api主动小程序了, 取而代之是navigator组件增加了一个exit的open-type.

[18-06-22]微信h5页面, 如果阻止了touch事件的默认动作, 会导致微信不会出现长按识别二维码菜单

经测试在安卓系统下会出现这种情况, 微信h5长按菜单说的是图片所示的菜单(截图于小米5)

微信长按菜单

document.getElementById('img').addEventListener('touchstart', (e) => {
  // 如果这里阻止默认行为, 会导致微信不能响应长按出现菜单
  e.preventDefault();
});
[18-06-19]原生js如何删除一个元素上所有的EventListener

在stackoverflow上找到的答案, 大致思路就是把复制那个元素, 然后用复制的元素替换掉旧的元素

需要注意的有两点, 一个是元素的子元素或内容很多时, 复制可能会耗费一定时间. 再来是这个操作只是删除了响应事件的目标DOM, 事实上事件处理回调函数的空间还是没有回收(如果形成闭包的话),容易造成内容泄露

const oldEl = document.getElementById('el-id'),
const newEL = el.cloneNode(true);

oldEl.parentNode.replaceChild(newEL, oldEl);
[18-06-12]使用webpack动态导入功能最终生成多个bundle时,如何指定异步加载的路径

设置output.publicPath为目标路径,可以使用url或路径,在production build的时候可以设置为线上的cdn地址的,然后把打包完成的资源直接上传到cdn即可

const config = {
  // ...
  output: {
    path: './dist', 
    filename: '[name].js',
    publicPath: 'https://my.cdn.com/assets/' // 最终bundleurl为 https://my.cdn.com/assets/[name].js
  }
  // ...
}