H5全端兼容视频保存相册,将 mp4 在线视频下载并存储到用户的手机相册中( ...

打印 上一主题 下一主题

主题 754|帖子 754|积分 2264


  • 文件下载分享保存相册

    • 用户点击页面时,应用会实验下载或分享指定的文件。
    • 如果设备支持分享(如移动设备上的 navigator.share API),文件将被直接分享。
    • 否则,文件将通过下载链接下载到用户设备。

  • 用户通知

    • 应用通过弹出通知向用户提供下载或分享的状态更新。

实现细节


  • HTML 和 CSS

    • 页面布局简便,以全屏背景图片和中央对齐的内容为主。
    • 通知弹窗使用 CSS 控制显示与匿伏,提供平滑的过渡效果。

  • Vue.js 应用

    • 使用 Vue.js 定义了一个简单的组件 App,包含数据属性和方法来处理文件操纵。

  • JavaScript 逻辑

    • handleDownload() 方法根据用户设备类型决定下载或分享逻辑。
    • fetchDownloadInfo() 模仿异步请求,从 URL 参数中提取文件链接。
    • showNotification() 方法用于在页面中央显示操纵反馈。

交互流程



  • 用户访问页面后,点击任意位置即会触发文件下载或分享。
  • 根据设备类型和功能支持,选择最佳方式(下载或分享)举行文件操纵。
  • 操纵的效果通过视觉通知反馈给用户,提升用户体验
    1. <!DOCTYPE html>
    2. <html lang="zh-CN">
    3. <head>
    4.     <meta charset="UTF-8">
    5.     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    6.     <title>文件下载和分享</title>
    7.     <style>
    8.         body {
    9.             margin: 0;
    10.             padding: 0;
    11.             background-image: url('https://img2.baidu.com/it/u=1819336312,2385547726&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1722445200&t=d2011eb7dab4b9fdb3e6e8dc425acb0c');
    12.             background-size: cover;
    13.             background-position: center;
    14.             font-family: Arial, sans-serif;
    15.             height: 100vh;
    16.             display: flex;
    17.             justify-content: center;
    18.             align-items: center;
    19.             cursor: pointer;
    20.             overflow: hidden;
    21.         }
    22.         .notification {
    23.             position: fixed;
    24.             top: 50%;
    25.             left: 50%;
    26.             transform: translate(-50%, -50%);
    27.             background-color: rgba(0, 0, 0, 0.8);
    28.             color: white;
    29.             padding: 10px 20px;
    30.             border-radius: 5px;
    31.             font-size: 16px;
    32.             opacity: 0;
    33.             pointer-events: none;
    34.             transition: opacity 0.5s;
    35.             z-index: 10;
    36.         }
    37.         .notification.show {
    38.             opacity: 1;
    39.         }
    40.     </style>
    41. </head>
    42. <body>
    43.     <div id="app">
    44.         <!-- Vue 模板将被挂载到这里 -->
    45.     </div>
    46.     <div id="notification" class="notification"></div>
    47.     <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    48.     <script src="https://cdn.jsdelivr.net/npm/vue-router@3"></script>
    49.     <script>
    50.         // Vue 组件
    51.         const App = {
    52.             data() {
    53.                 return {
    54.                     downloadLink: '',
    55.                 };
    56.             },
    57.             methods: {
    58.                 async handleDownload() {
    59.                     const downloadInfo = await this.fetchDownloadInfo();
    60.                     if (!downloadInfo) {
    61.                         this.showNotification('下载失败');
    62.                         return;
    63.                     }
    64.                     const link = downloadInfo.query.downloadLink;
    65.                     const fileName = link.substring(link.lastIndexOf('/') + 1);
    66.                     if (this.isMobile() && navigator.share) {
    67.                         this.showLoading();
    68.                         try {
    69.                             const fileBlob = await (await fetch(link)).blob();
    70.                             this.hideLoading();
    71.                             const shareData = { files: [new File([fileBlob], fileName, { type: fileBlob.type })] };
    72.                             if (navigator.canShare(shareData)) {
    73.                                 await navigator.share(shareData);
    74.                                 this.showNotification('下载成功了 (Download success)');
    75.                             } else {
    76.                                 throw new Error('无法分享');
    77.                             }
    78.                         } catch (error) {
    79.                             console.error(error);
    80.                             this.retryDownload();
    81.                         }
    82.                     } else {
    83.                         this.downloadFile(link, fileName);
    84.                     }
    85.                 },
    86.                 downloadFile(url, fileName) {
    87.                     // 直接跳转到下载链接,而不是创建临时元素
    88.                     window.location.href = url;
    89.                     this.showNotification('下载开始了 (Download started)');
    90.                 },
    91.                 showNotification(message) {
    92.                     const notification = document.getElementById('notification');
    93.                     notification.textContent = message;
    94.                     notification.classList.add('show');
    95.                     setTimeout(() => {
    96.                         notification.classList.remove('show');
    97.                     }, 1500);
    98.                 },
    99.                 showLoading() {
    100.                     this.showNotification('下载资源中...');
    101.                 },
    102.                 hideLoading() {
    103.                     this.showNotification('下载资源中...');
    104.                 },
    105.                 retryDownload() {
    106.                     console.log('尝试重新下载');
    107.                     window.location.reload();
    108.                 },
    109.                 isMobile() {
    110.                     return /Mobi|Android/i.test(navigator.userAgent);
    111.                 },
    112.                 fetchDownloadInfo() {
    113.                     // 提取完整的 URL
    114.                     const params = new URLSearchParams(window.location.search);
    115.                     const downloadUrl = params.get('file'); // 获取完整的 URL
    116.                     return new Promise((resolve) => {
    117.                         setTimeout(() => {
    118.                             resolve({ query: { downloadLink: downloadUrl } });
    119.                         }, 500); // 减少延迟时间
    120.                     });
    121.                 }
    122.             },
    123.             mounted() {
    124.                 // 添加页面点击事件来触发下载
    125.                 document.body.addEventListener('click', this.handleDownload);
    126.             },
    127.             template: `
    128.                 <div>
    129.                     <p></p>
    130.                 </div>
    131.             `
    132.         };
    133.         // 定义路由
    134.         const routes = [];
    135.         // 创建路由实例
    136.         const router = new VueRouter({
    137.             mode: 'history',
    138.             routes
    139.         });
    140.         // 创建 Vue 实例
    141.         new Vue({
    142.             router,
    143.             render: h => h(App)
    144.         }).$mount('#app');
    145.     </script>
    146. </body>
    147. </html>
    复制代码
    必要留意navigator.share API只能在https情况直接拉起使用
测试使用地点后面直接拼接参数https://your.com/share.html?file=https://your.com/2029005.mp4


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

拉不拉稀肚拉稀

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表