引言:移动分享功能的重要性与挑战

在移动互联网时代,分享功能已成为App和网站不可或缺的核心特性。根据最新统计,拥有便捷分享功能的产品用户留存率平均提升35%,传播效率提升超过200%。然而,移动端的分享实现远比桌面端复杂,涉及iOS、Android、微信、微博等众多平台,每个平台都有独特的分享机制和限制。

本文将从零开始,全面讲解如何使用JavaScript实现移动端分享功能,涵盖基础实现、高级技巧、跨平台集成以及常见问题的解决方案。无论你是前端开发新手还是资深工程师,都能从中获得实用的知识和代码示例。

1. 移动端分享基础概念

1.1 移动端分享的三种主要方式

  1. 原生分享API:iOS的UIActivityViewController和Android的Intent系统
  2. Web Share API:现代浏览器提供的标准分享接口
  3. SDK集成:微信、微博等平台提供的专用SDK

1.2 分享功能的核心要素

  • 分享内容:标题、描述、图片、链接
  • 目标平台:社交平台、通讯工具、邮件等
  • 用户授权:获取用户同意分享
  • 回调处理:分享成功或失败的反馈

2. 基础实现:Web Share API

Web Share API是W3C推荐的标准API,支持在支持的浏览器中调用系统原生分享面板。

2.1 基本使用方法

// 检测浏览器是否支持Web Share API
if (navigator.share) {
    // 基础分享示例
    async function shareContent() {
        try {
            await navigator.share({
                title: '精彩内容推荐',
                text: '这个网站提供了非常实用的开发技巧,强烈推荐!',
                url: 'https://example.com/article/123'
            });
            console.log('分享成功');
        } catch (error) {
            if (error.name !== 'AbortError') {
                console.error('分享失败:', error);
            }
        }
    }
} else {
    // 降级处理
    console.log('当前浏览器不支持Web Share API');
    // 使用自定义分享面板或复制链接功能
}

2.2 Web Share API的高级用法

// 带图片分享(部分浏览器支持)
async function shareWithImage() {
    // 首先需要将图片转换为File对象
    const response = await fetch('/path/to/image.jpg');
    const blob = await response.blob();
    const file = new File([blob], 'image.jpg', { type: 'image/jpeg' });

    try {
        await navigator.share({
            title: '产品图片',
            text: '查看这个精美的产品图片',
            files: [file]
        });
    } catch (1.2.3) {
        console.error('分享失败:', error);
    }
}

// 分享当前页面
async function shareCurrentPage() {
    if (navigator.share) {
        await navigator.share({
            title: document.title,
            text: '查看这个页面',
            url: window.location.href
        });
    }
}

2.3 Web Share API的兼容性数据

浏览器 iOS Safari Android Chrome 微信浏览器 UC浏览器
支持版本 12.2+ 75+ 部分支持 部分支持
文件分享 支持 部分支持 不支持 不支持
自定义面板 系统原生 系统原生 自定义 自定义

3. 平台特定实现:微信与微博分享

3.1 微信分享实现

微信分享需要使用微信JS-SDK,这是微信官方提供的网页开发工具包。

3.1.1 微信JS-SDK配置

// 1. 引入微信JS-SDK
import wx from 'weixin-js-sdk';

// 2. 配置微信JS-SDK
function initWeChatShare() {
    // 获取微信配置信息(需要后端接口提供)
    fetch('/api/wechat/config?url=' + encodeURIComponent(window.location.href))
        .then(response => response.json())
        .then(config => {
            wx.config({
                debug: false, // 开启调试模式
                appId: config.appId, // 必填,公众号的唯一标识
                timestamp: config.timestamp, // 必填,生成签名的时间戳
                nonceStr: config.nonceStr, // 必填,生成签名的随机串
                signature: config.signature, // 必填,签名
                jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareAppMessage', 'onMenuShareTimeline'] // 必填,需要使用的JS接口列表
            });

            wx.ready(function() {
                // 配置分享信息
                setWeChatShareData();
            });

            wx.error(function(res) {
                console.error('微信JS-SDK配置失败:', res);
            });
        });
}

// 3. 设置微信分享数据
function setWeChatShareData() {
    const shareData = {
        title: '精彩内容推荐', // 分享标题
        desc: '这个网站提供了非常实用的开发技巧,强烈推荐!', // 分享描述
        link: 'https://example.com/article/123', // 分享链接
        imgUrl: 'https://example.com/images/share.jpg', // 分享图标
        success: function() {
            console.log('分享成功');
            // 可以在这里添加统计代码
        },
        cancel: function() {
            console.log('用户取消分享');
        }
    };

    // 分享给朋友
    wx.updateAppMessageShareData(shareData);
    // 分享到朋友圈
    wx.updateTimelineShareData(shareData);

    // 旧版API兼容
    wx.onMenuShareAppMessage(shareData);
    wx.onMenuShareTimeline(shareData);
}

3.1.2 微信分享的后端签名实现(Node.js示例)

const crypto = require('crypto');
const axios = require('axios');

// 获取微信access_token
async function getWeChatAccessToken() {
    const appId = 'your_app_id';
    const appSecret = 'your_app_secret';
    const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`;
    
    const response = await axios.get(url);
    return response.data.access_token;
}

// 获取微信jsapi_ticket
async function getWeChatJsApiTicket(accessToken) {
    const url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`;
    const response = await axios.get(url);
    return response.data.ticket;
}

// 生成签名
function generateSignature(ticket, nonceStr, timestamp, url) {
    const string1 = `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
    const shasum = crypto.createHash('sha1');
    shasum.update(string1);
    return shasum.digest('hex');
}

// Express路由示例
app.get('/api/wechat/config', async (req, res) => {
    try {
        const url = req.query.url;
        const accessToken = await getWeChatAccessToken();
        const ticket = await getWeChatJsApiTicket(accessToken);
        
        const nonceStr = Math.random().toString(36).substr(2, 15);
        const timestamp = Math.floor(Date.now() / 1000);
        const signature = generateSignature(ticket, nonceStr, timestamp, url);
        
        res.json({
            appId: 'your_app_id',
            timestamp,
            nonceStr,
            signature
        });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

3.2 微博分享实现

微博分享相对简单,主要通过URL参数实现。

// 微博分享函数
function shareToWeibo() {
    const title = encodeURIComponent('精彩内容推荐');
    const url = encodeURIComponent('https://example.com/article/123');
    const imageUrl = encodeURIComponent('https://example.com/images/share.jpg');
    
    // 构建微博分享URL
    const weiboUrl = `http://service.weibo.com/share/share.php?url=${url}&title=${title}&pic=${imageUrl}&appkey=your_app_key`;
    
    // 打开分享窗口
    window.open(weiboUrl, '_blank', 'width=600,height=400,toolbar=no,menubar=no,scrollbars=no, resizable=yes,location=no,status=no');
}

// 微博分享按钮点击事件
document.getElementById('share-weibo').addEventListener('click', shareToWeibo);

4. 高级技巧:自定义分享面板与优化

4.1 自定义分享面板实现

当浏览器不支持Web Share API或需要自定义样式时,可以创建自己的分享面板。

<!-- HTML结构 -->
<div id="custom-share-panel" class="share-panel hidden">
    <div class="share-header">
        <h3>分享到</h3>
        <button class="close-btn">&times;</button>
    </div>
    <div class="share-options">
        <button class="share-option" data-platform="wechat">
            <span class="icon">💚</span>
            <span>微信</span>
        </button>
        <button class="share-option" data-platform="weibo">
            <span class="icon">新浪微博</span>
            <span>微博</span>
        </button>
        <button class="share-option" data-platform="copy">
            <span class="icon">📋</span>
            <span>复制链接</span>
        </button>
        <button class="share-option" data-platform="more">
            <span class="icon">•••</span>
            <span>更多</span>
        </button>
    </div>
</div>
<div id="share-overlay" class="overlay hidden"></div>
/* CSS样式 */
.share-panel {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: white;
    border-radius: 16px 16px 0 0;
    z-index: 1000;
    transform: translateY(100%);
    transition: transform 0.3s ease;
}

.share-panel.visible {
    transform: translateY(0);
}

.share-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid #eee;
}

.share-options {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    padding: 16px;
}

.share-option {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: none;
    border: none;
    padding: 8px;
    cursor: pointer;
}

.share-option .icon {
    font-size: 24px;
    margin-bottom: 4px;
}

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
}

.hidden {
    display: none;
}
// JavaScript逻辑
class CustomSharePanel {
    constructor() {
        this.panel = document.getElementById('custom-share-panel');
        this.overlay = document.getElementById('share-overlay');
        this.closeBtn = this.panel.querySelector('.close-btn');
        this.shareOptions = this.panel.querySelectorAll('.share-option');
        
        this.initEvents();
    }
    
    initEvents() {
        // 关闭面板
        this.closeBtn.addEventListener('click', () => this.hide());
        this.overlay.addEventListener('click', () => this.hide());
        
        // 分享选项点击
        this.shareOptions.forEach(option => {
            option.addEventListener('click', (e) => {
                const platform = e.currentTarget.dataset.platform;
                this.handleShare(platform);
            });
        });
    }
    
    show() {
        this.panel.classList.add('visible');
        this.overlay.classList.remove('hidden');
        document.body.style.overflow = 'hidden';
    }
    
    hide() {
        this.panel.classList.remove('visible');
        this.overlay.classList.add('hidden');
        document.body.style.overflow = '';
    }
    
    async handleShare(platform) {
        const shareData = {
            title: document.title,
            text: '查看这个精彩内容',
            url: window.location.href
        };
        
        switch(platform) {
            case 'wechat':
                // 如果在微信内,使用微信SDK
                if (this.isWeChat()) {
                    await this.shareViaWeChat(shareData);
                } else {
                    // 显示二维码
                    this.showQRCode(shareData.url);
                }
                break;
                
            case 'weibo':
                this.shareViaWeibo(shareData);
                break;
                
            case 'copy':
                await this.copyLink(shareData.url);
                break;
                
            case 'more':
                await this.shareViaSystem(shareData);
                break;
        }
        
        this.hide();
    }
    
    isWeChat() {
        return /MicroMessenger/i.test(navigator.userAgent);
    }
    
    async shareViaWeChat(data) {
        if (typeof wx !== 'undefined') {
            // 使用微信SDK分享
            wx.updateAppMessageShareData({
                title: data.title,
                desc: data.text,
                link: data.url,
                imgUrl: 'https://example.com/images/share.jpg',
                success: () => console.log('微信分享成功')
            });
        } else {
            this.showQRCode(data.url);
        }
    }
    
    shareViaWeibo(data) {
        const weiboUrl = `http://service.weibo.com/share/share.php?url=${encodeURIComponent(data.url)}&title=${encodeURIComponent(data.title + ' ' + data.text)}`;
        window.open(weiboUrl, '_blank', 'width=600,height=400');
    }
    
    async copyLink(url) {
        try {
            await navigator.clipboard.writeText(url);
            this.showToast('链接已复制到剪贴板');
        } catch (error) {
            // 降级方案
            const textArea = document.createElement('textarea');
            textArea.value = url;
            document.body.appendChild(textArea);
            textArea.select();
            document.execCommand('copy');
            document.body.removeChild(textArea);
            this.showToast('链接已复制到剪贴板');
        }
    }
    
    async shareViaSystem(data) {
        if (navigator.share) {
            try {
                await navigator.share(data);
            } catch (error) {
                console.log('系统分享取消或失败');
            }
        } else {
            this.showToast('当前设备不支持系统分享');
        }
    }
    
    showQRCode(url) {
        // 生成二维码并显示
        const qrContainer = document.createElement('div');
        qrContainer.innerHTML = `
            <div style="text-align:center; padding:20px;">
                <h3>微信扫一扫分享</h3>
                <div id="qrcode" style="margin:20px auto;"></div>
                <p style="font-size:12px; color:#666;">请使用微信扫描二维码</p>
            </div>
        `;
        
        // 使用QRCode.js生成二维码
        if (typeof QRCode !== 'undefined') {
            new QRCode(qrContainer.querySelector('#qrcode'), {
                text: url,
                width: 150,
                height: 150
            });
        }
        
        // 显示模态框
        this.showModal(qrContainer.innerHTML);
    }
    
    showModal(content) {
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 12px;
            z-index: 1001;
            max-width: 90%;
        `;
        modal.innerHTML = content + '<button onclick="this.parentElement.remove()" style="margin-top:10px; padding:8px 16px; background:#007bff; color:white; border:none; border-radius:4px;">关闭</button>';
        
        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 1000;
        `;
        
        overlay.addEventListener('click', () => {
            modal.remove();
            overlay.remove();
        });
        
        document.body.appendChild(overlay);
        document.body.appendChild(modal);
    }
    
    showToast(message) {
        const toast = document.createElement('div');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: #333;
            color: white;
            padding: 12px 24px;
            border-radius: 24px;
            z-index: 1002;
            animation: fadeInOut 2s ease;
        `;
        
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.remove();
        }, 2000);
    }
}

// 初始化
const sharePanel = new CustomSharePanel();

// 暴露全局方法供调用
window.showSharePanel = () => sharePanel.show();

4.2 分享性能优化策略

4.2.1 懒加载分享资源

// 按需加载微信JS-SDK
async function loadWeChatSDK() {
    if (typeof wx === 'undefined') {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js';
            script.onload = () => resolve();
            script.onerror = () => reject(new Error('Failed to load WeChat SDK'));
            document.head.appendChild(script);
        });
    }
    return Promise.resolve();
}

// 按需初始化分享功能
async function initShareOnDemand() {
    // 检测用户是否可能分享(例如,用户点击了分享按钮)
    const shareButton = document.getElementById('share-btn');
    if (shareButton) {
        shareButton.addEventListener('click', async () => {
            // 只在用户需要时加载SDK
            if (isWeChatBrowser()) {
                await loadWeChatSDK();
                await initWeChatShare();
            }
            // 显示分享面板
            showSharePanel();
        });
    }
}

4.2.2 分享数据预加载与缓存

// 分享数据缓存管理器
class ShareDataCache {
    constructor() {
        this.cache = new Map();
        this.ttl = 5 * 60 * 1000; // 5分钟缓存
    }
    
    set(key, data) {
        this.cache.set(key, {
            data,
            timestamp: Date.now()
        });
    }
    
    get(key) {
        const item = this.cache.get(key);
        if (!item) return null;
        
        if (Date.now() - item.timestamp > this.ttl) {
            this.cache.delete(key);
            return null;
        }
        
        return item.data;
    }
    
    clear() {
        this.cache.clear();
    }
}

const shareCache = new ShareDataCache();

// 预加载分享数据
async function preloadShareData() {
    const cacheKey = `share_${window.location.pathname}`;
    const cachedData = shareCache.get(cacheKey);
    
    if (cachedData) {
        return cachedData;
    }
    
    // 从服务器获取分享数据
    try {
        const response = await fetch(`/api/share-data?url=${encodeURIComponent(window.location.href)}`);
        const data = await response.json();
        
        // 缓存数据
        shareCache.set(cacheKey, data);
        
        return data;
    } catch (error) {
        console.error('获取分享数据失败:', error);
        // 返回默认数据
        return {
            title: document.title,
            description: '查看这个页面',
            image: 'https://example.com/default-share.jpg'
        };
    }
}

// 在页面加载时预加载
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', preloadShareData);
} else {
    preloadShareData();
}

5. 常见兼容性问题与解决方案

5.1 iOS与Android的差异处理

5.1.1 iOS分享问题

// iOS特定处理
class iOSShareHandler {
    constructor() {
        this.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
        this.isIOS122Above = false;
        
        if (this.isIOS) {
            const version = this.getIOSVersion();
            this.isIOS122Above = version >= 12.2;
        }
    }
    
    getIOSVersion() {
        const match = navigator.userAgent.match(/OS (\d+)_(\d+)_?(\d+)?/);
        if (!match) return 0;
        return parseFloat(match[1] + '.' + match[2]);
    }
    
    // iOS 12.2+ 使用Web Share API
    async shareViaWebShare(data) {
        if (!this.isIOS122Above || !navigator.share) {
            return false;
        }
        
        try {
            await navigator.share(data);
            return true;
        } catch (error) {
            return false;
        }
    }
    
    // iOS 12.2以下使用自定义方案
    shareViaCustom(data) {
        // iOS Safari不支持复制功能,需要特殊处理
        if (this.isIOS) {
            // 创建隐藏的输入框用于复制
            const input = document.createElement('input');
            input.style.position = 'fixed';
            input.style.opacity = '0';
            input.value = data.url;
            document.body.appendChild(input);
            input.select();
            
            try {
                document.execCommand('copy');
                this.showIOSToast('链接已复制,请到微信中粘贴分享');
            } catch (e) {
                this.showIOSToast('复制失败,请手动复制链接');
            }
            
            document.body.removeChild(input);
        }
    }
    
    showIOSToast(message) {
        // iOS风格的toast
        const toast = document.createElement('div');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 12px 20px;
            border-radius: 8px;
            font-size: 14px;
            z-index: 10000;
            max-width: 80%;
            text-align: center;
        `;
        
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transition = 'opacity 0.3s';
            setTimeout(() => toast.remove(), 300);
        }, 2000);
    }
}

// 使用示例
const iosHandler = new iOSShareHandler();

5.1.2 Android分享问题

// Android特定处理
class AndroidShareHandler {
    constructor() {
        this.isAndroid = /Android/.test(navigator.userAgent);
        this.isChrome = /Chrome/.test(navigator.userAgent);
    }
    
    // Android Web Share API支持检测
    async checkWebShareSupport() {
        if (!this.isAndroid) return false;
        
        // Android Chrome 75+ 支持Web Share API
        const chromeVersion = this.getChromeVersion();
        return chromeVersion >= 75 && navigator.share;
    }
    
    getChromeVersion() {
        const match = navigator.userAgent.match(/Chrome\/(\d+)/);
        return match ? parseInt(match[1]) : 0;
    }
    
    // Android微信浏览器处理
    isWeChatBrowser() {
        return /MicroMessenger/i.test(navigator.userAgent);
    }
    
    // Android分享到微信
    shareToWeChatAndroid(data) {
        if (this.isWeChatBrowser()) {
            // 在微信内,显示提示
            this.showAndroidToast('点击右上角菜单分享给朋友');
            return;
        }
        
        // 非微信浏览器,使用Intent分享
        if (navigator.share) {
            navigator.share(data).catch(() => {
                // 降级到Intent
                this.shareViaIntent(data);
            });
        } else {
            this.shareViaIntent(data);
        }
    }
    
    shareViaIntent(data) {
        // Android Intent分享
        const intentUrl = `intent://share/#Intent;scheme=mailto;package=com.android.email;S.subject=${encodeURIComponent(data.title)};S.body=${encodeURIComponent(data.text + ' ' + data.url)};end`;
        
        // 尝试启动Intent
        window.location.href = intentUrl;
        
        // 如果Intent失败,显示提示
        setTimeout(() => {
            if (document.hidden) return;
            this.showAndroidToast('请使用系统分享功能');
        }, 1000);
    }
    
    showAndroidToast(message) {
        const toast = document.createElement('div');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: #323232;
            color: white;
            padding: 14px 24px;
            border-radius: 2px;
            z-index: 10000;
            font-size: 14px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        `;
        
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.style.transition = 'opacity 0.3s, transform 0.3s';
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(-50%) translateY(-20px)';
            setTimeout(() => toast.remove(), 300);
        }, 2000);
    }
}

5.2 微信浏览器特殊处理

微信浏览器是移动端分享最复杂的场景,需要多种策略组合。

// 微信浏览器综合处理
class WeChatBrowserHandler {
    constructor() {
        this.isWeChat = /MicroMessenger/i.test(navigator.userAgent);
        this.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
        this.isAndroid = /Android/.test(navigator.userAgent);
    }
    
    // 主分享方法
    async share(data) {
        if (!this.isWeChat) {
            return this.shareOutsideWeChat(data);
        }
        
        // 在微信内
        if (this.isIOS) {
            return this.shareInWeChatIOS(data);
        } else if (this.isAndroid) {
            return this.shareInWeChatAndroid(data);
        }
    }
    
    // 在微信内(iOS)
    async shareInWeChatIOS(data) {
        // iOS微信内,Web Share API不可用
        // 需要使用微信JS-SDK或显示引导图
        
        // 检查是否已加载JS-SDK
        if (typeof wx === 'undefined') {
            // 显示引导用户点击右上角菜单
            this.showWeChatGuide('iOS');
            return;
        }
        
        // 使用JS-SDK分享
        try {
            await this.shareViaJSSDK(data);
        } catch (error) {
            this.showWeChatGuide('iOS');
        }
    }
    
    // 在微信内(Android)
    async shareInWeChatAndroid(data) {
        // Android微信内,部分版本支持Web Share API
        if (navigator.share) {
            try {
                await navigator.share(data);
                return;
            } catch (error) {
                // 继续使用JS-SDK
            }
        }
        
        // 使用JS-SDK
        if (typeof wx !== 'undefined') {
            try {
                await this.shareViaJSSDK(data);
                return;
            } catch (error) {
                // 继续使用引导图
            }
        }
        
        this.showWeChatGuide('Android');
    }
    
    // 在微信外
    async shareOutsideWeChat(data) {
        // 优先使用Web Share API
        if (navigator.share) {
            try {
                await navigator.share(data);
                return;
            } catch (error) {
                // 继续使用其他方案
            }
        }
        
        // 显示自定义分享面板
        if (window.showSharePanel) {
            window.showSharePanel();
        } else {
            // 复制链接
            await this.copyLink(data.url);
        }
    }
    
    // 使用微信JS-SDK
    async shareViaJSSDK(data) {
        return new Promise((resolve, reject) => {
            // 分享给朋友
            wx.updateAppMessageShareData({
                title: data.title,
                desc: data.text,
                link: data.url,
                imgUrl: data.image || 'https://example.com/share.jpg',
                success: () => resolve(),
                cancel: () => reject(new Error('用户取消'))
            });
            
            // 分享到朋友圈
            wx.updateTimelineShareData({
                title: data.title,
                link: data.url,
                imgUrl: data.image || 'https://example.com/share.jpg',
                success: () => resolve(),
                cancel: () => reject(new Error('用户取消'))
            });
        });
    }
    
    // 显示微信引导图
    showWeChatGuide(platform) {
        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.8);
            z-index: 9999;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            color: white;
            text-align: center;
            padding: 20px;
        `;
        
        const guideText = platform === 'iOS' 
            ? '点击右上角菜单,选择"分享给朋友"' 
            : '点击右上角菜单,选择"分享"';
        
        overlay.innerHTML = `
            <div style="font-size: 18px; margin-bottom: 20px;">${guideText}</div>
            <div style="font-size: 14px; opacity: 0.8;">或点击右上角菜单,选择"在浏览器中打开"</div>
            <button id="close-guide" style="margin-top: 30px; padding: 10px 20px; background: white; color: black; border: none; border-radius: 4px;">关闭</button>
        `;
        
        document.body.appendChild(overlay);
        
        overlay.querySelector('#close-guide').addEventListener('click', () => {
            overlay.remove();
        });
        
        // 点击遮罩关闭
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        });
    }
    
    // 复制链接
    async copyLink(url) {
        try {
            await navigator.clipboard.writeText(url);
            this.showToast('链接已复制');
        } catch (error) {
            // 降级方案
            const textArea = document.createElement('textarea');
            textArea.value = url;
            document.body.appendChild(textArea);
            textArea.select();
            document.execCommand('copy');
            document.body.removeChild(textArea);
            this.showToast('链接已复制');
        }
    }
    
    showToast(message) {
        const toast = document.createElement('div');
        toast.textContent = message;
        toast.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 12px 24px;
            border-radius: 8px;
            z-index: 10000;
        `;
        
        document.body.appendChild(toast);
        
        setTimeout(() => {
            toast.remove();
        }, 2000);
    }
}

// 使用示例
const wechatHandler = new WeChatBrowserHandler();

5.3 复制链接功能的兼容性处理

// 复制链接的完整解决方案
class ClipboardHandler {
    constructor() {
        this.isSupported = this.checkSupport();
    }
    
    checkSupport() {
        return {
            clipboardAPI: !!navigator.clipboard,
            execCommand: !!document.execCommand,
            ios: /iPad|iPhone|iPod/.test(navigator.userAgent),
            android: /Android/.test(navigator.userAgent)
        };
    }
    
    async copy(text) {
        // 优先使用现代Clipboard API
        if (this.isSupported.clipboardAPI) {
            try {
                await navigator.clipboard.writeText(text);
                return { success: true, method: 'clipboardAPI' };
            } catch (error) {
                // 继续尝试其他方法
            }
        }
        
        // iOS特殊处理
        if (this.isSupported.ios) {
            return this.copyIOS(text);
        }
        
        // Android特殊处理
        if (this.isSupported.android) {
            return this.copyAndroid(text);
        }
        
        // 降级到execCommand
        if (this.isSupported.execCommand) {
            return this.copyExecCommand(text);
        }
        
        // 最终降级
        return this.copyFallback(text);
    }
    
    // iOS复制方案
    copyIOS(text) {
        // iOS需要用户交互才能复制,创建临时输入框
        const input = document.createElement('input');
        input.style.cssText = `
            position: fixed;
            opacity: 0;
            top: -1000px;
            left: -1000px;
        `;
        input.value = text;
        document.body.appendChild(input);
        
        // 选中并复制
        input.contentEditable = true;
        input.readOnly = false;
        
        // 创建选区
        const range = document.createRange();
        range.selectNodeContents(input);
        
        const selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
        
        // 尝试复制
        let success = false;
        try {
            success = document.execCommand('copy');
        } catch (e) {
            success = false;
        }
        
        // 清理
        selection.removeAllRanges();
        document.body.removeChild(input);
        
        return { 
            success, 
            method: 'execCommand_ios',
            message: success ? '复制成功' : 'iOS复制失败,请手动长按复制'
        };
    }
    
    // Android复制方案
    copyAndroid(text) {
        // Android某些版本需要特殊处理
        const textArea = document.createElement('textarea');
        textArea.style.cssText = `
            position: fixed;
            opacity: 0;
            top: 0;
            left: 0;
            width: 1px;
            height: 1px;
        `;
        textArea.value = text;
        document.body.appendChild(textArea);
        
        textArea.select();
        
        let success = false;
        try {
            success = document.execCommand('copy');
        } catch (e) {
            success = false;
        }
        
        document.body.removeChild(textArea);
        
        return {
            success,
            method: 'execCommand_android',
            message: success ? '复制成功' : '复制失败,请手动复制'
        };
    }
    
    // 标准execCommand方案
    copyExecCommand(text) {
        const textArea = document.createElement('textarea');
        textArea.style.cssText = `
            position: fixed;
            opacity: 0;
            top: 0;
            left: 0;
            width: 1px;
            height: 1px;
        `;
        textArea.value = text;
        document.body.appendChild(textArea);
        
        textArea.select();
        
        let success = false;
        try {
            success = document.execCommand('copy');
        } catch (e) {
            success = false;
        }
        
        document.body.removeChild(textArea);
        
        return {
            success,
            method: 'execCommand',
            message: success ? '复制成功' : '复制失败'
        };
    }
    
    // 最终降级方案
    copyFallback(text) {
        // 显示文本供用户手动复制
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            z-index: 10001;
            max-width: 90%;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
        `;
        
        modal.innerHTML = `
            <h3 style="margin: 0 0 15px 0;">请手动复制链接</h3>
            <textarea style="width: 100%; height: 80px; margin-bottom: 10px; padding: 8px; border: 1px solid #ddd; border-radius: 4px;" readonly>${text}</textarea>
            <button style="width: 100%; padding: 10px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;" onclick="this.parentElement.remove()">关闭</button>
        `;
        
        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 10000;
        `;
        
        overlay.addEventListener('click', () => {
            modal.remove();
            overlay.remove();
        });
        
        document.body.appendChild(overlay);
        document.body.appendChild(modal);
        
        return {
            success: false,
            method: 'fallback',
            message: '已显示链接供手动复制'
        };
    }
}

// 使用示例
const clipboardHandler = new ClipboardHandler();

// 按钮点击事件
document.getElementById('copy-link-btn').addEventListener('click', async () => {
    const result = await clipboardHandler.copy(window.location.href);
    
    if (result.success) {
        showToast('链接已复制到剪贴板');
    } else {
        showToast(result.message);
    }
});

6. 分享功能的优化策略

6.1 分享数据的动态生成

// 动态生成分享数据
class DynamicShareData {
    constructor() {
        this.defaultData = {
            title: document.title,
            description: '查看这个页面',
            image: 'https://example.com/default-share.jpg',
            url: window.location.href
        };
    }
    
    // 根据页面内容生成分享数据
    async generateFromContent() {
        // 提取页面标题
        const title = this.extractTitle();
        
        // 提取描述(从meta标签或内容)
        const description = this.extractDescription();
        
        // 提取图片
        const image = this.extractImage();
        
        // 构建分享数据
        return {
            title,
            description,
            image,
            url: this.buildShareUrl()
        };
    }
    
    extractTitle() {
        // 优先使用og:title
        const ogTitle = document.querySelector('meta[property="og:title"]');
        if (ogTitle) return ogTitle.content;
        
        // 其次使用页面标题
        const title = document.querySelector('h1');
        if (title) return title.textContent;
        
        // 最后使用document.title
        return document.title;
    }
    
    extractDescription() {
        // 优先使用og:description
        const ogDesc = document.querySelector('meta[property="og:description"]');
        if (ogDesc) return ogDesc.content;
        
        // 其次使用meta description
        const metaDesc = document.querySelector('meta[name="description"]');
        if (metaDesc) return metaDesc.content;
        
        // 最后提取第一段内容
        const paragraphs = document.querySelectorAll('p');
        if (paragraphs.length > 0) {
            return paragraphs[0].textContent.substring(0, 100) + '...';
        }
        
        return this.defaultData.description;
    }
    
    extractImage() {
        // 优先使用og:image
        const ogImage = document.querySelector('meta[property="og:image"]');
        if (ogImage) return ogImage.content;
        
        // 其次查找页面中的图片
        const images = document.querySelectorAll('img');
        for (let img of images) {
            // 选择尺寸合适的图片
            if (img.naturalWidth >= 200 && img.naturalHeight >= 200) {
                return img.src;
            }
        }
        
        return this.defaultData.image;
    }
    
    buildShareUrl() {
        // 添加分享标记参数
        const url = new URL(window.location.href);
        url.searchParams.set('share_source', 'app');
        url.searchParams.set('share_timestamp', Date.now());
        return url.toString();
    }
    
    // 为特定平台优化数据
    optimizeForPlatform(data, platform) {
        const optimized = { ...data };
        
        switch(platform) {
            case 'wechat':
                // 微信分享标题限制32字符
                if (optimized.title.length > 32) {
                    optimized.title = optimized.title.substring(0, 29) + '...';
                }
                // 描述限制128字符
                if (optimized.description.length > 128) {
                    optimized.description = optimized.description.substring(0, 125) + '...';
                }
                break;
                
            case 'weibo':
                // 微博标题限制2000字符,但建议控制在140字符内
                if (optimized.title.length > 140) {
                    optimized.title = optimized.title.substring(0, 137) + '...';
                }
                break;
                
            case 'system':
                // 系统分享,保持原样
                break;
        }
        
        return optimized;
    }
}

// 使用示例
const shareDataGenerator = new DynamicShareData();

// 在需要分享时
async function handleShare() {
    const rawData = await shareDataGenerator.generateFromContent();
    const wechatData = shareDataGenerator.optimizeForPlatform(rawData, 'wechat');
    
    // 使用优化后的数据进行分享
    if (wechatHandler.isWeChatBrowser()) {
        await wechatHandler.share(wechatData);
    } else {
        await shareViaSystem(wechatData);
    }
}

6.2 分享统计与追踪

// 分享统计管理器
class ShareTracker {
    constructor() {
        this.trackingId = this.generateTrackingId();
        this.shareEvents = [];
    }
    
    generateTrackingId() {
        return 'share_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    }
    
    // 记录分享事件
    async trackShare(platform, data) {
        const event = {
            trackingId: this.trackingId,
            platform,
            timestamp: Date.now(),
            url: window.location.href,
            title: data.title,
            userId: this.getUserId(),
            sessionId: this.getSessionId()
        };
        
        this.shareEvents.push(event);
        
        // 发送到服务器
        try {
            await fetch('/api/analytics/share', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(event)
            });
        } catch (error) {
            console.error('发送分享统计失败:', error);
            // 本地存储,稍后重试
            this.storeOfflineEvent(event);
        }
    }
    
    // 记录分享成功
    async trackShareSuccess(platform, trackingId) {
        const event = {
            trackingId,
            platform,
            timestamp: Date.now(),
            type: 'success'
        };
        
        try {
            await fetch('/api/analytics/share/success', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(event)
            });
        } catch (error) {
            console.error('发送成功统计失败:', error);
        }
    }
    
    // 记录分享失败
    async trackShareFailure(platform, trackingId, error) {
        const event = {
            trackingId,
            platform,
            timestamp: Date.now(),
            type: 'failure',
            error: error.message
        };
        
        try {
            await fetch('/api/analytics/share/failure', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(event)
            });
        } catch (error) {
            console.error('发送失败统计失败:', error);
        }
    }
    
    // 获取用户ID
    getUserId() {
        let userId = localStorage.getItem('user_id');
        if (!userId) {
            userId = 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            localStorage.setItem('user_id', userId);
        }
        return userId;
    }
    
    // 获取会话ID
    getSessionId() {
        let sessionId = sessionStorage.getItem('session_id');
        if (!sessionId) {
            sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            sessionStorage.setItem('session_id', sessionId);
        }
        return sessionId;
    }
    
    // 离线事件存储
    storeOfflineEvent(event) {
        const offlineEvents = JSON.parse(localStorage.getItem('offline_share_events') || '[]');
        offlineEvents.push(event);
        localStorage.setItem('offline_share_events', JSON.stringify(offlineEvents));
        
        // 尝试重试发送
        this.retryOfflineEvents();
    }
    
    // 重试离线事件
    async retryOfflineEvents() {
        const offlineEvents = JSON.parse(localStorage.getItem('offline_share_events') || '[]');
        if (offlineEvents.length === 0) return;
        
        const successfulEvents = [];
        
        for (const event of offlineEvents) {
            try {
                await fetch('/api/analytics/share', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(event)
                });
                successfulEvents.push(event);
            } catch (error) {
                // 保留失败的事件
            }
        }
        
        // 移除成功的事件
        const remainingEvents = offlineEvents.filter(e => !successfulEvents.includes(e));
        localStorage.setItem('offline_share_events', JSON.stringify(remainingEvents));
    }
    
    // 获取分享统计
    async getShareStats(timeRange = '7d') {
        try {
            const response = await fetch(`/api/analytics/share/stats?range=${timeRange}`);
            return await response.json();
        } catch (error) {
            console.error('获取统计失败:', error);
            return null;
        }
    }
}

// 使用示例
const shareTracker = new ShareTracker();

// 包装分享函数以添加统计
async function shareWithTracking(platform, data) {
    const trackingId = shareTracker.generateTrackingId();
    
    // 记录分享开始
    await shareTracker.trackShare(platform, data);
    
    try {
        // 执行分享
        await performShare(platform, data);
        
        // 记录成功
        await shareTracker.trackShareSuccess(platform, trackingId);
        
        // 显示成功提示
        showToast('分享成功!');
    } catch (error) {
        // 记录失败
        await shareTracker.trackShareFailure(platform, trackingId, error);
        
        // 显示失败提示
        showToast('分享失败: ' + error.message);
    }
}

6.3 分享性能监控

// 分享性能监控
class SharePerformanceMonitor {
    constructor() {
        this.metrics = {
            shareInitTime: 0,
            shareExecutionTime: 0,
            shareSuccessRate: 0,
            platformDistribution: {}
        };
    }
    
    // 开始监控
    startMonitoring() {
        this.metrics.shareInitTime = performance.now();
    }
    
    // 记录分享执行时间
    recordExecutionTime(startTime, endTime) {
        this.metrics.shareExecutionTime = endTime - startTime;
    }
    
    // 记录分享结果
    recordResult(platform, success) {
        // 更新成功率
        const total = Object.values(this.metrics.platformDistribution).reduce((a, b) => a + b, 0) + 1;
        const successes = Object.values(this.metrics.platformDistribution).reduce((a, b) => a + b, 0) + (success ? 1 : 0);
        this.metrics.shareSuccessRate = (successes / total) * 100;
        
        // 更新平台分布
        if (!this.metrics.platformDistribution[platform]) {
            this.metrics.platformDistribution[platform] = 0;
        }
        this.metrics.platformDistribution[platform] += success ? 1 : 0;
    }
    
    // 获取性能报告
    getPerformanceReport() {
        return {
            ...this.metrics,
            timestamp: Date.now(),
            userAgent: navigator.userAgent,
            screenResolution: `${screen.width}x${screen.height}`
        };
    }
    
    // 发送性能数据
    async sendPerformanceReport() {
        const report = this.getPerformanceReport();
        
        try {
            await fetch('/api/analytics/performance', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(report)
            });
        } catch (error) {
            console.error('发送性能报告失败:', error);
        }
    }
}

// 使用示例
const perfMonitor = new SharePerformanceMonitor();

// 在分享函数中使用
async function monitoredShare(platform, data) {
    perfMonitor.startMonitoring();
    const startTime = performance.now();
    
    try {
        await performShare(platform, data);
        const endTime = performance.now();
        
        perfMonitor.recordExecutionTime(startTime, endTime);
        perfMonitor.recordResult(platform, true);
        
        // 定期发送报告(例如每10次分享)
        if (Math.random() < 0.1) {
            await perfMonitor.sendPerformanceReport();
        }
    } catch (error) {
        perfMonitor.recordResult(platform, false);
        throw error;
    }
}

7. 安全考虑

7.1 分享链接的安全处理

// 安全分享链接生成器
class SecureShareLinkGenerator {
    constructor() {
        this.secretKey = 'your-secret-key'; // 实际使用时应从后端获取
    }
    
    // 生成带签名的分享链接
    generateSignedLink(baseUrl, params = {}) {
        const timestamp = Date.now();
        const nonce = this.generateNonce();
        
        // 添加签名参数
        const signedParams = {
            ...params,
            _ts: timestamp,
            _nonce: nonce,
            _sign: this.generateSignature(baseUrl, params, timestamp, nonce)
        };
        
        const url = new URL(baseUrl);
        Object.entries(signedParams).forEach(([key, value]) => {
            url.searchParams.set(key, value);
        });
        
        return url.toString();
    }
    
    // 验证分享链接
    verifySignedLink(urlString) {
        try {
            const url = new URL(urlString);
            const params = Object.fromEntries(url.searchParams.entries());
            
            // 提取签名相关参数
            const { _ts, _nonce, _sign, ...actualParams } = params;
            
            // 检查时间戳(5分钟有效期)
            const now = Date.now();
            if (now - parseInt(_ts) > 5 * 60 * 1000) {
                return { valid: false, reason: '链接已过期' };
            }
            
            // 验证签名
            const expectedSign = this.generateSignature(url.origin + url.pathname, actualParams, parseInt(_ts), _nonce);
            if (_sign !== expectedSign) {
                return { valid: false, reason: '签名验证失败' };
            }
            
            return { valid: true, params: actualParams };
        } catch (error) {
            return { valid: false, reason: '链接格式错误' };
        }
    }
    
    // 生成签名
    generateSignature(baseUrl, params, timestamp, nonce) {
        const sortedParams = Object.entries(params)
            .sort(([a], [b]) => a.localeCompare(b))
            .map(([k, v]) => `${k}=${v}`)
            .join('&');
        
        const stringToSign = `${baseUrl}?${sortedParams}&_ts=${timestamp}&_nonce=${nonce}&key=${this.secretKey}`;
        
        // 使用SHA256生成签名
        if (typeof crypto !== 'undefined' && crypto.subtle) {
            // 浏览器环境
            // 注意:实际使用中,签名应在后端生成,前端只负责验证
            return this.simpleHash(stringToSign);
        } else {
            // Node.js环境或其他
            return this.simpleHash(stringToSign);
        }
    }
    
    // 简单的哈希函数(实际使用应使用更安全的加密库)
    simpleHash(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // 转换为32位整数
        }
        return hash.toString(16);
    }
    
    // 生成随机数
    generateNonce() {
        return Math.random().toString(36).substr(2, 15) + 
               Math.random().toString(36).substr(2, 15);
    }
    
    // 生成防重放令牌
    generateReplayToken() {
        return 'replay_' + Date.now() + '_' + this.generateNonce();
    }
}

// 使用示例
const secureLinkGenerator = new SecureShareLinkGenerator();

// 生成分享链接
function generateSecureShareLink(contentId, userId) {
    const baseUrl = 'https://example.com/content';
    const params = {
        id: contentId,
        ref: userId,
        utm_source: 'share',
        utm_medium: 'mobile'
    };
    
    return secureLinkGenerator.generateSignedLink(baseUrl, params);
}

// 验证接收到的链接
function validateReceivedLink(url) {
    const result = secureLinkGenerator.verifySignedLink(url);
    
    if (!result.valid) {
        console.error('无效的分享链接:', result.reason);
        return false;
    }
    
    console.log('链接验证通过,参数:', result.params);
    return true;
}

7.2 防止分享滥用

// 分享频率限制器
class ShareRateLimiter {
    constructor() {
        this.limits = {
            perMinute: 10,    // 每分钟最多10次
            perHour: 50,      // 每小时最多50次
            perDay: 200       // 每天最多200次
        };
        
        this.storageKey = 'share_rate_limits';
    }
    
    // 检查是否可以分享
    canShare() {
        const now = Date.now();
        const records = this.getRecords();
        
        // 清理过期记录
        const validRecords = records.filter(time => now - time < 24 * 60 * 60 * 1000);
        
        // 检查各时间段限制
        const minuteCount = validRecords.filter(time => now - time < 60 * 1000).length;
        const hourCount = validRecords.filter(time => now - time < 60 * 60 * 1000).length;
        const dayCount = validRecords.length;
        
        if (minuteCount >= this.limits.perMinute) {
            return { allowed: false, reason: '分享过于频繁,请稍后再试' };
        }
        
        if (hourCount >= this.limits.perHour) {
            return { allowed: false, reason: '已达到每小时分享上限' };
        }
        
        if (dayCount >= this.limits.perDay) {
            return { allowed: false, reason: '已达到每日分享上限' };
        }
        
        return { allowed: true };
    }
    
    // 记录分享行为
    recordShare() {
        const records = this.getRecords();
        records.push(Date.now());
        
        // 只保留最近24小时的记录
        const cutoff = Date.now() - 24 * 60 * 60 * 1000;
        const filtered = records.filter(time => time > cutoff);
        
        localStorage.setItem(this.storageKey, JSON.stringify(filtered));
    }
    
    // 获取记录
    getRecords() {
        try {
            const stored = localStorage.getItem(this.storageKey);
            return stored ? JSON.parse(stored) : [];
        } catch (error) {
            return [];
        }
    }
    
    // 清除记录(用于测试或用户登出时)
    clearRecords() {
        localStorage.removeItem(this.storageKey);
    }
    
    // 获取剩余等待时间
    getWaitTime() {
        const now = Date.now();
        const records = this.getRecords();
        
        if (records.length === 0) return 0;
        
        const lastShare = Math.max(...records);
        const nextAllowedTime = lastShare + 60 * 1000; // 1分钟间隔
        
        if (now >= nextAllowedTime) return 0;
        
        return nextAllowedTime - now;
    }
}

// 使用示例
const rateLimiter = new ShareRateLimiter();

// 分享按钮点击处理
document.getElementById('share-btn').addEventListener('click', async () => {
    // 检查频率限制
    const check = rateLimiter.canShare();
    
    if (!check.allowed) {
        showToast(check.reason);
        
        // 显示等待时间
        const waitTime = rateLimiter.getWaitTime();
        if (waitTime > 0) {
            const seconds = Math.ceil(waitTime / 1000);
            showToast(`请等待 ${seconds} 秒后再试`);
        }
        
        return;
    }
    
    // 执行分享
    try {
        await performShare();
        
        // 记录成功分享
        rateLimiter.recordShare();
        
        showToast('分享成功!');
    } catch (error) {
        showToast('分享失败: ' + error.message);
    }
});

8. 测试与调试

8.1 分享功能测试工具

// 分享功能测试工具
class ShareTestTool {
    constructor() {
        this.testCases = [];
        this.results = [];
    }
    
    // 添加测试用例
    addTestCase(name, testFn) {
        this.testCases.push({ name, testFn });
    }
    
    // 运行所有测试
    async runAllTests() {
        console.log('开始运行分享功能测试...');
        
        for (const testCase of this.testCases) {
            try {
                const result = await testCase.testFn();
                this.results.push({
                    name: testCase.name,
                    status: 'PASS',
                    result
                });
                console.log(`✓ ${testCase.name}: PASS`);
            } catch (error) {
                this.results.push({
                    name: testCase.name,
                    status: 'FAIL',
                    error: error.message
                });
                console.error(`✗ ${testCase.name}: FAIL - ${error.message}`);
            }
        }
        
        console.log('测试完成');
        return this.results;
    }
    
    // 生成测试报告
    generateReport() {
        const total = this.results.length;
        const passed = this.results.filter(r => r.status === 'PASS').length;
        const failed = total - passed;
        
        return {
            summary: {
                total,
                passed,
                failed,
                successRate: (passed / total * 100).toFixed(2) + '%'
            },
            details: this.results
        };
    }
    
    // 显示测试报告
    showReport() {
        const report = this.generateReport();
        
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            z-index: 10001;
            max-width: 90%;
            max-height: 80vh;
            overflow: auto;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
        `;
        
        let html = `
            <h2>分享功能测试报告</h2>
            <div style="margin: 10px 0; padding: 10px; background: #f0f0f0; border-radius: 4px;">
                <p>总测试数: ${report.summary.total}</p>
                <p>通过: <span style="color: green;">${report.summary.passed}</span></p>
                <p>失败: <span style="color: red;">${report.summary.failed}</span></p>
                <p>成功率: ${report.summary.successRate}</p>
            </div>
            <h3>详细结果:</h3>
            <ul style="list-style: none; padding: 0;">
        `;
        
        report.details.forEach(detail => {
            const color = detail.status === 'PASS' ? 'green' : 'red';
            const icon = detail.status === 'PASS' ? '✓' : '✗';
            html += `<li style="margin: 5px 0; color: ${color};">${icon} ${detail.name}`;
            if (detail.error) {
                html += `<br><small style="color: #666;">${detail.error}</small>`;
            }
            html += `</li>`;
        });
        
        html += `
            </ul>
            <button onclick="this.parentElement.remove()" style="margin-top: 15px; padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px;">关闭</button>
        `;
        
        modal.innerHTML = html;
        
        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 10000;
        `;
        
        overlay.addEventListener('click', () => {
            modal.remove();
            overlay.remove();
        });
        
        document.body.appendChild(overlay);
        document.body.appendChild(modal);
    }
}

// 创建测试工具实例
const shareTestTool = new ShareTestTool();

// 添加测试用例
shareTestTool.addTestCase('Web Share API支持检测', async () => {
    const supported = !!navigator.share;
    if (!supported) {
        throw new Error('浏览器不支持Web Share API');
    }
    return '支持';
});

shareTestTool.addTestCase('微信浏览器检测', async () => {
    const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
    return isWeChat ? '在微信内' : '不在微信内';
});

shareTestTool.addTestCase('剪贴板API支持检测', async () => {
    const supported = !!navigator.clipboard;
    if (!supported) {
        throw new Error('不支持Clipboard API');
    }
    return '支持';
});

shareTestTool.addTestCase('iOS版本检测', async () => {
    const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    if (isIOS) {
        const match = navigator.userAgent.match(/OS (\d+)_(\d+)/);
        if (match) {
            return `iOS ${match[1]}.${match[2]}`;
        }
    }
    return '非iOS设备';
});

shareTestTool.addTestCase('Android版本检测', async () => {
    const isAndroid = /Android/.test(navigator.userAgent);
    if (isAndroid) {
        const match = navigator.userAgent.match(/Android (\d+)/);
        if (match) {
            return `Android ${match[1]}`;
        }
    }
    return '非Android设备';
});

// 运行测试按钮
document.addEventListener('DOMContentLoaded', () => {
    const testBtn = document.createElement('button');
    testBtn.textContent = '运行分享功能测试';
    testBtn.style.cssText = `
        position: fixed;
        bottom: 20px;
        right: 20px;
        padding: 10px 15px;
        background: #28a745;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        z-index: 9999;
        font-size: 14px;
    `;
    
    testBtn.addEventListener('click', async () => {
        testBtn.disabled = true;
        testBtn.textContent = '测试中...';
        
        await shareTestTool.runAllTests();
        shareTestTool.showReport();
        
        testBtn.disabled = false;
        testBtn.textContent = '运行分享功能测试';
    });
    
    document.body.appendChild(testBtn);
});

9. 最佳实践总结

9.1 移动端分享功能设计原则

  1. 渐进增强:从最基础的复制链接开始,逐步添加更高级的功能
  2. 优雅降级:当高级功能不可用时,提供备用方案
  3. 用户友好:提供清晰的反馈和引导
  4. 性能优先:按需加载资源,避免阻塞页面渲染
  5. 安全第一:验证分享链接,防止滥用

9.2 代码组织建议

// 推荐的代码组织结构
class MobileShareManager {
    constructor(config = {}) {
        this.config = {
            enableTracking: true,
            enableRateLimiting: true,
            fallbackToCopy: true,
            ...config
        };
        
        this.handlers = {
            system: new SystemShareHandler(),
            wechat: new WeChatShareHandler(),
            weibo: new WeiboShareHandler(),
            clipboard: new ClipboardHandler()
        };
        
        this.tracker = new ShareTracker();
        this.rateLimiter = new ShareRateLimiter();
        this.cache = new ShareDataCache();
    }
    
    // 主分享方法
    async share(platform, data) {
        // 检查频率限制
        if (this.config.enableRateLimiting) {
            const limitCheck = this.rateLimiter.canShare();
            if (!limitCheck.allowed) {
                throw new Error(limitCheck.reason);
            }
        }
        
        // 获取优化后的数据
        const optimizedData = await this.getOptimizedData(data, platform);
        
        // 执行分享
        try {
            const handler = this.getHandler(platform);
            await handler.share(optimizedData);
            
            // 记录成功
            if (this.config.enableTracking) {
                await this.tracker.trackShareSuccess(platform, data.trackingId);
            }
            
            // 记录频率
            if (this.config.enableRateLimiting) {
                this.rateLimiter.recordShare();
            }
            
            return { success: true };
        } catch (error) {
            // 记录失败
            if (this.config.enableTracking) {
                await this.tracker.trackShareFailure(platform, data.trackingId, error);
            }
            
            // 尝试降级
            if (this.config.fallbackToCopy && platform !== 'clipboard') {
                return this.share('clipboard', data);
            }
            
            throw error;
        }
    }
    
    // 获取合适的处理器
    getHandler(platform) {
        // 智能选择处理器
        if (platform === 'auto') {
            if (this.handlers.wechat.isWeChatBrowser()) {
                return this.handlers.wechat;
            }
            if (navigator.share) {
                return this.handlers.system;
            }
            return this.handlers.clipboard;
        }
        
        if (!this.handlers[platform]) {
            throw new Error(`不支持的平台: ${platform}`);
        }
        
        return this.handlers[platform];
    }
    
    // 获取优化后的数据
    async getOptimizedData(data, platform) {
        // 从缓存获取
        const cacheKey = `${platform}_${JSON.stringify(data)}`;
        const cached = this.cache.get(cacheKey);
        if (cached) return cached;
        
        // 优化数据
        let optimized = { ...data };
        
        // 平台特定优化
        if (platform === 'wechat') {
            optimized = this.optimizeForWeChat(optimized);
        } else if (platform === 'weibo') {
            optimized = this.optimizeForWeibo(optimized);
        }
        
        // 缓存结果
        this.cache.set(cacheKey, optimized);
        
        return optimized;
    }
    
    optimizeForWeChat(data) {
        // 微信标题限制32字符
        if (data.title.length > 32) {
            data.title = data.title.substring(0, 29) + '...';
        }
        // 描述限制128字符
        if (data.description && data.description.length > 128) {
            data.description = data.description.substring(0, 125) + '...';
        }
        return data;
    }
    
    optimizeForWeibo(data) {
        // 微博建议控制在140字符内
        if (data.title.length > 140) {
            data.title = data.title.substring(0, 137) + '...';
        }
        return data;
    }
}

// 使用示例
const shareManager = new MobileShareManager({
    enableTracking: true,
    enableRateLimiting: true
});

// 简单的分享调用
async function shareContent(platform = 'auto') {
    const data = {
        title: document.title,
        description: '查看这个精彩内容',
        url: window.location.href,
        image: 'https://example.com/share.jpg'
    };
    
    try {
        await shareManager.share(platform, data);
        showToast('分享成功!');
    } catch (error) {
        showToast('分享失败: ' + error.message);
    }
}

10. 未来趋势与展望

10.1 Web Share API的发展

Web Share API正在成为移动端分享的标准方式。随着浏览器厂商的持续支持,未来将有更多功能加入:

  • 文件分享:更多浏览器支持分享文件
  • 自定义目标:允许指定特定应用分享
  • 分享目标检测:检测用户实际分享到的平台

10.2 原生与Web的融合

随着PWA(Progressive Web Apps)的发展,Web应用将获得更多的原生能力,包括更强大的分享功能。Flutter、React Native等跨平台框架也在不断完善分享插件。

10.3 AI驱动的分享优化

未来可能出现基于AI的分享优化:

  • 智能推荐分享平台:根据用户习惯推荐最佳分享渠道
  • 自动优化分享内容:根据目标平台自动调整内容格式
  • 分享效果预测:预测分享后的传播效果

结论

移动端分享功能的实现需要综合考虑多种因素:平台兼容性、用户体验、性能优化和安全性。通过本文的详细讲解和代码示例,你应该已经掌握了从基础到高级的分享实现技巧。

记住,最好的分享功能是用户几乎感觉不到存在的功能——它应该在需要时出现,在不需要时隐形,并且始终提供可靠的降级方案。持续测试、监控和优化你的分享功能,确保它在不断变化的移动环境中保持最佳状态。

最后,分享功能的成功不仅取决于技术实现,更取决于对用户需求的深刻理解和对细节的持续打磨。希望这篇全面的指南能帮助你构建出色的移动端分享体验!