H5全端兼容视频保存相册,将 mp4 在线视频下载并存储到用户的手机相册中(完整代码)
测试使用地址后面直接拼接参数。
·
-
文件下载分享保存相册:
- 用户点击页面时,应用会尝试下载或分享指定的文件。
- 如果设备支持分享(如移动设备上的
navigator.share
API),文件将被直接分享。 - 否则,文件将通过下载链接下载到用户设备。
-
用户通知:
- 应用通过弹出通知向用户提供下载或分享的状态更新。
实现细节
-
HTML 和 CSS:
- 页面结构简洁,以全屏背景图片和中央对齐的内容为主。
- 通知弹窗使用 CSS 控制显示与隐藏,提供平滑的过渡效果。
-
Vue.js 应用:
- 使用 Vue.js 定义了一个简单的组件
App
,包含数据属性和方法来处理文件操作。
- 使用 Vue.js 定义了一个简单的组件
-
JavaScript 逻辑:
handleDownload()
方法根据用户设备类型决定下载或分享逻辑。fetchDownloadInfo()
模拟异步请求,从 URL 参数中提取文件链接。showNotification()
方法用于在页面中央显示操作反馈。
交互流程
- 用户访问页面后,点击任意位置即会触发文件下载或分享。
- 根据设备类型和功能支持,选择最佳方式(下载或分享)进行文件操作。
- 操作的结果通过视觉通知反馈给用户,提升用户体验
需要注意navigator.share API只能在https环境直接拉起使用<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> <title>文件下载和分享</title> <style> body { margin: 0; padding: 0; 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'); background-size: cover; background-position: center; font-family: Arial, sans-serif; height: 100vh; display: flex; justify-content: center; align-items: center; cursor: pointer; overflow: hidden; } .notification { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px 20px; border-radius: 5px; font-size: 16px; opacity: 0; pointer-events: none; transition: opacity 0.5s; z-index: 10; } .notification.show { opacity: 1; } </style> </head> <body> <div id="app"> <!-- Vue 模板将被挂载到这里 --> </div> <div id="notification" class="notification"></div> <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <script src="https://cdn.jsdelivr.net/npm/vue-router@3"></script> <script> // Vue 组件 const App = { data() { return { downloadLink: '', }; }, methods: { async handleDownload() { const downloadInfo = await this.fetchDownloadInfo(); if (!downloadInfo) { this.showNotification('下载失败'); return; } const link = downloadInfo.query.downloadLink; const fileName = link.substring(link.lastIndexOf('/') + 1); if (this.isMobile() && navigator.share) { this.showLoading(); try { const fileBlob = await (await fetch(link)).blob(); this.hideLoading(); const shareData = { files: [new File([fileBlob], fileName, { type: fileBlob.type })] }; if (navigator.canShare(shareData)) { await navigator.share(shareData); this.showNotification('下载成功了 (Download success)'); } else { throw new Error('无法分享'); } } catch (error) { console.error(error); this.retryDownload(); } } else { this.downloadFile(link, fileName); } }, downloadFile(url, fileName) { // 直接跳转到下载链接,而不是创建临时元素 window.location.href = url; this.showNotification('下载开始了 (Download started)'); }, showNotification(message) { const notification = document.getElementById('notification'); notification.textContent = message; notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 1500); }, showLoading() { this.showNotification('下载资源中...'); }, hideLoading() { this.showNotification('下载资源中...'); }, retryDownload() { console.log('尝试重新下载'); window.location.reload(); }, isMobile() { return /Mobi|Android/i.test(navigator.userAgent); }, fetchDownloadInfo() { // 提取完整的 URL const params = new URLSearchParams(window.location.search); const downloadUrl = params.get('file'); // 获取完整的 URL return new Promise((resolve) => { setTimeout(() => { resolve({ query: { downloadLink: downloadUrl } }); }, 500); // 减少延迟时间 }); } }, mounted() { // 添加页面点击事件来触发下载 document.body.addEventListener('click', this.handleDownload); }, template: ` <div> <p></p> </div> ` }; // 定义路由 const routes = []; // 创建路由实例 const router = new VueRouter({ mode: 'history', routes }); // 创建 Vue 实例 new Vue({ router, render: h => h(App) }).$mount('#app'); </script> </body> </html>
测试使用地址后面直接拼接参数https://your.com/share.html?file=https://your.com/2029005.mp4
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献2条内容
所有评论(0)