Cef 模式下,Vue @click 事件偶尔无效问题

Cef 模式下,Vue 项目 @click 事件偶尔无效问题

Cef 模式:使用 C++ 创建的一个浏览器,有它自己的浏览器内核版本

在 Cef Web 壳子中开发时候,发现 Vue 项目 的 @click 偶尔就无效,一开始还以为电脑卡了,具体分析后发现不是这样的。
原因分析(vue2):

通过打断点分析,看到 @click 事件执行用到了下面代码的判断

if (
  e.target === e.currentTarget ||
  e.timeStamp >= attachedTimestamp || //产生问题的一行
  e.timeStamp <= 0 ||
  e.target.ownerDocument !== document
) {
  return original.apply(this, arguments);
}

问题产生的原因应该就是 Cef 模式下手动事件时间戳发生了延迟(前几秒一直为 0)
因此我们要想办法让这个判断不利用时间戳执行下去

原因分析(vue3):

通过打断点分析,看到 @click 事件执行用到了下面代码的判断

function createInvoker(initialValue, instance) {
  const invoker = (e) => {
    const timeStamp = e.timeStamp || _getNow();
    if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
      callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
    }
  };
  invoker.value = initialValue;
  invoker.attached = getNow();
  return invoker;
}

不需要看懂,只需要知道这里也是时间戳的问题
因此我们要想办法让这个判断不利用时间戳执行下去

解决问题:
Vue2

利用 e.target === e.currentTarget 这个判断条件进行验证:

e.currentTarget: 绑定事件的元素
e.target: 实际点击的元素(冒泡,最下面那个元素)

不难分析出,只需要让绑定 @click 的 dom 元素成为 e.target 即可。
使用 css 一个属性即可解决

/* 绑定 @click 事件的 DOM 元素类名 */
.click-dom > * {
  pointer-events: none;
}
Vue3

利用 skipTimestampCheck 这个判断条件进行验证:
想法设法让它变为 true
源代码中设置 skipTimestampCheck 的位置如下:

if (typeof window !== "undefined") {
  // Determine what event timestamp the browser is using. Annoyingly, the
  // timestamp can either be hi-res (relative to page load) or low-res
  // (relative to UNIX epoch), so in order to compare time we have to use the
  // same timestamp type when saving the flush timestamp.
  if (_getNow() > document.createEvent("Event").timeStamp) {
    // if the low-res timestamp which is bigger than the event timestamp
    // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
    // and we need to use the hi-res version for event listeners as well.
    _getNow = () => performance.now();
  }
  // #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
  // and does not fire microtasks in between event propagation, so safe to exclude.
  const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
  skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
}

所以,在我们的 Vue3 项目中,在 index.html 添加:

<!DOCTYPE html>
<html lang="en">
  <head>
    ....
    <script>
      // 添加这一行!!!
      Object.defineProperty(window.navigator, 'userAgent', {value:'firefox/53'});
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

综上,所有解决办法如下:

  • 升级 Cef 版本,相关 issues :issues
  • Vue2
/* 绑定 @click 事件的 DOM 元素类名 */
.click-dom > * {
  pointer-events: none;
}
  • Vue3
<!DOCTYPE html>
<html lang="en">
  <head>
    ....
    <script>
      // 添加这一行!!!
      Object.defineProperty(window.navigator, 'userAgent', {value:'firefox/53'});
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

如有错误或不解,欢迎评论区指正!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
GIF动态预览图: 开发环境: E2EE支持库 (已集成) CEF框架(已集成) VUE -https://cn.vuejs.org/ (已集成) NodeJS (已集成) WebPack (已集成) HTML/CSS/JS (已集成) 易语言 (已集成) 易主程序源码参考 lib ---- CEF运行库,必须 (目录名禁止修改) server ---- 本地服务器网站目录,必须 图标 ---- 自带的图标,可删除 jingyi.e ---- 主程序源代码 精益论坛PC版DEMO.exe ---- 主程序成品,必须 Chromium Embedded Framework 3.ec ---- CEF调用模块 Installer32.dll ---- CEF 扩展DLL,必须 libtransfer.dll ---- CEF 扩展DLL,必须 以上标注“必须”为整个程序生产编译后的依赖项,否则无法正常运行 VUE界面源码参考 由于环境模块过大,所以不附带 初始化安装环境步骤: 1、请将当前目录的yarn.lock 删除 2、在当前目录下打开CMD,输入指令“yarn”回车即可自动安装环境 3、安装好环境包后,在当前目录执行CMD指令“yarn serve”回车即可运行调试 4、yarn build 命令 一键打包发布,发布后的内容在当前dist目录下,打包完成后会自动生成 5、将打包后的dist网页内容复制到,易语言主程序下的server目录替换即可 以上为有HTML,CSS,JS基础,以及会VUE框架的人使用,如果您不会VUE,您需要学习后在来操作。 我们已经把打包后的VUE成品界面内置到了主程序的server目录,您不需要对VUE源码项目做任何操作 您只需要运行主程序即可看到效果 该项目主要由易语言+CEF+VUE+E2EE来完成,懂这方面的人员可以自行修改源码,如果您不会也可以自己尝试修改,便于学习 界面UI部分是由前端VUE框架构建 如有会这方面的人,可以自行扩展

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值