wechat-detector.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * 微信环境检测工具
  3. * 用于检测是否在微信浏览器中,并提供跳转浏览器的功能
  4. */
  5. /**
  6. * 检测是否在微信环境中
  7. * @returns {boolean} 是否在微信中
  8. */
  9. export function isWechat(): boolean {
  10. const ua = navigator.userAgent.toLowerCase();
  11. return /micromessenger/.test(ua);
  12. }
  13. /**
  14. * 检测平台类型
  15. * @returns {object} 平台信息
  16. */
  17. export function getPlatform() {
  18. const ua = navigator.userAgent.toLowerCase();
  19. return {
  20. isAndroid: /android/.test(ua),
  21. isIOS: /iphone|ipad|ipod/.test(ua),
  22. isWechat: /micromessenger/.test(ua),
  23. };
  24. }
  25. /**
  26. * 尝试在浏览器中打开当前页面
  27. * @param {string} url - 要打开的URL,默认为当前页面URL
  28. * @returns {boolean} 是否成功触发跳转
  29. */
  30. export function openInBrowser(url?: string): boolean {
  31. const targetUrl = url || window.location.href;
  32. const platform = getPlatform();
  33. try {
  34. if (platform.isAndroid) {
  35. // 安卓可以直接尝试打开浏览器
  36. // 方法1: 尝试使用 intent:// 协议(适用于微信内置浏览器)
  37. try {
  38. const urlObj = new URL(targetUrl);
  39. const intentUrl = `intent://${urlObj.host}${urlObj.pathname}${urlObj.search}#Intent;scheme=https;package=com.android.chrome;end`;
  40. // 使用隐藏的 iframe 尝试跳转
  41. const iframe = document.createElement('iframe');
  42. iframe.style.display = 'none';
  43. iframe.style.width = '1px';
  44. iframe.style.height = '1px';
  45. iframe.src = intentUrl;
  46. document.body.appendChild(iframe);
  47. // 延迟移除 iframe,给跳转一些时间
  48. setTimeout(() => {
  49. try {
  50. document.body.removeChild(iframe);
  51. } catch (e) {
  52. // 忽略移除失败
  53. }
  54. }, 1000);
  55. // 同时尝试直接跳转(作为备选方案)
  56. setTimeout(() => {
  57. window.location.href = targetUrl;
  58. }, 500);
  59. return true;
  60. } catch (e) {
  61. // 如果 intent 失败,直接跳转
  62. window.location.href = targetUrl;
  63. return true;
  64. }
  65. } else if (platform.isIOS) {
  66. // iOS 在微信中无法直接跳转,需要用户手动操作
  67. // 这里尝试直接跳转(可能会失败,但至少尝试)
  68. window.location.href = targetUrl;
  69. return true;
  70. } else {
  71. // 其他平台直接跳转
  72. window.location.href = targetUrl;
  73. return true;
  74. }
  75. } catch (error) {
  76. return false;
  77. }
  78. }
  79. /**
  80. * 复制链接到剪贴板
  81. * @param {string} url - 要复制的URL,默认为当前页面URL
  82. * @returns {Promise<boolean>} 是否成功复制
  83. */
  84. export async function copyToClipboard(url?: string): Promise<boolean> {
  85. const targetUrl = url || window.location.href;
  86. try {
  87. if (navigator.clipboard && navigator.clipboard.writeText) {
  88. await navigator.clipboard.writeText(targetUrl);
  89. return true;
  90. } else {
  91. // 降级方案:使用传统的复制方法
  92. const textArea = document.createElement('textarea');
  93. textArea.value = targetUrl;
  94. textArea.style.position = 'fixed';
  95. textArea.style.left = '-999999px';
  96. textArea.style.top = '-999999px';
  97. document.body.appendChild(textArea);
  98. textArea.focus();
  99. textArea.select();
  100. try {
  101. const successful = document.execCommand('copy');
  102. document.body.removeChild(textArea);
  103. return successful;
  104. } catch (err) {
  105. document.body.removeChild(textArea);
  106. return false;
  107. }
  108. }
  109. } catch (error) {
  110. return false;
  111. }
  112. }