当前位置: 首页 > news >正文

js实现跨域下载,展示下载进度以及自定义下载名称功能

在这里插入图片描述

一、 下载进度

  1. loading弹窗结构
// loading状态DOM
function setLoading() {
    let content = document.querySelector('.loading')
    content.innerHTML = ''
    content.innerHTML = `
    <div class="loading_content">
        <div class="contentBox">
            <div class="downloadTip">
                <div class="tips">下载成功!</div>
                <div class="close">
                    <img src="../img/img1/close.png" alt="">
                </div>
            </div>


            <div class="box">
                <div class="tip">预计下载时长10-15s, 请耐心等待</div>
                <div class="progress-container">
                    <div class="progress-bar"></div>
                    <div class="progress-text"></div>
                    <div class="particles">
                        <div class="particle"></div>
                        <div class="particle"></div>
                        <div class="particle"></div>
                        <div class="particle"></div>
                        <div class="particle"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    `
}
  1. loading弹窗样式

.loading_content{
    /* display: none; */
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.7);
    z-index: 5;
    font-size: 15px;
}


.loading_content .contentBox {
    display: block;
    position: relative;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 337px;
    height: 168px;
    padding: 20px;
    background:  url("../img/dialog.png") no-repeat center;
    background-size: contain;
}

.loading_content .contentBox .box ,
.loading_content .contentBox .downloadTip{
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}
.loading_content .contentBox .downloadTip {
    position: relative;
    display: none;
    color: #fff;
}
.loading_content .contentBox .downloadTip .close {
    position: absolute;
    cursor: pointer;
    top: 0;
    right: 0;
    width: 25px!important;
    height: 25px!important;
}
.loading_content .contentBox .downloadTip .close img {
    width: 100%;
    height: 100%;
}
.loading_content .contentBox .downloadTip .tips {
    position: relative;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 50%;
    line-height: 84px;
    text-align: center;
    transform: translateX(-50%) translateY(-50%);
    font-size: 22px;
}

.loading_content .contentBox .box .tip {
    width: 100%;
    text-align: center;
    line-height: 75px;
    color: #C9B387;
}


.progress-container {
    position: relative;
    width: 100%;
    max-width: 500px;
    height: 20px;
    background: radial-gradient(circle, #1b2735, #090a0f);
    border-radius: 30px;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
    box-sizing: border-box;
    border: 1px solid #313131;
  }
  
  .progress-bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: linear-gradient(90deg, #c9b386, rgb(146, 24, 22));
    border-radius: 30px;
    animation: grow 7s ease-in forwards;
    box-shadow:
      0 0 15px #c9b386,
      0 0 30px rgb(146, 24, 22);
  }
  
  .progress-bar::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 200%;
    height: 200%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.15), transparent);
    opacity: 0.5;
    animation: ripple 15s infinite;
  }
  
  .progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 10px;
    font-weight: bold;
    letter-spacing: 1px;
    color: #fff;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.7);
    z-index: 2;
  }
  
  .particles {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
  
  .particle {
    position: absolute;
    width: 4px;
    height: 4px;
    background: #fff;
    border-radius: 50%;
    opacity: 0.6;
    animation: float 5s infinite ease-in-out;
  }
  
  @keyframes grow {
    0% {
      width: 0;
    }
    100% {
      width: 99%;
    }
  }
  
  @keyframes ripple {
    0% {
      transform: translate(-50%, -50%) scale(0.5);
      opacity: 0.7;
    }
    100% {
      transform: translate(-50%, -50%) scale(1.5);
      opacity: 0;
    }
  }
  
  @keyframes float {
    0% {
      transform: translateY(0) translateX(0);
    }
    50% {
      transform: translateY(-20px) translateX(10px);
    }
    100% {
      transform: translateY(0) translateX(0);
    }
  }
  .particle:nth-child(1) {
    top: 10%;
    left: 20%;
    animation-delay: 0s;
  }
  .particle:nth-child(2) {
    top: 30%;
    left: 70%;
    animation-delay: 1s;
  }
  .particle:nth-child(3) {
    top: 50%;
    left: 50%;
    animation-delay: 2s;
  }
  .particle:nth-child(4) {
    top: 80%;
    left: 40%;
    animation-delay: 1.5s;
  }
  .particle:nth-child(5) {
    top: 90%;
    left: 60%;
    animation-delay: 2.5s;
  }
  
  1. 开始显示loading
// 开始动画
function loadingStart() {
    let text = document.querySelector('.progress-text')
    text.innerText = '0%'
    let flag = 0
    timer = setInterval(() => {
        if (text.innerText == '99%') {
            clearInterval(timer)
            return
        }
        flag += 7
        if (flag == 98) {
            flag = 99
        }
        let data = flag
        text.innerText = `${data}%`
    }, 500)
}
  1. 结束loading状态
}
// 结束动画
function loadingDone() {
    timer && clearInterval(timer)
    // 下载完成
    $('.progress-text').html('100%')
    $('.progress-bar').css('animation', 'unset')
    $('.progress-bar').css('width', '100%')
    setTimeout(() => {
        // 结果页面显示,loading页面隐藏
        $('.box').css('display', 'none')
        $('.downloadTip').css('display', 'block')
        $('.close').click(function () {
            $('.loading').html('')
        });
    }, 1500)
}

二、 跨域下载与 自定义名称

主要通过请求获取blob来进行下载

  1. 获取blob
// 异步下载任务
function getBlob(url) {
   return new Promise(resolve => {
       try {
           const xhr = new XMLHttpRequest();
           xhr.open('GET', url, true);
           xhr.responseType = 'blob';
           xhr.onload = () => {
               if (xhr.status === 200) {
                   resolve(xhr.response);
               } else {
                   window.location.href = url;
                   $('.loading').html('')
               }
           };
           xhr.send();
       } catch (error) {
           window.location.href = url;
           $('.loading').html('')
       }

   });
}
  1. 下载与命名

function downloadHandler(blob, url, code) {
    let name = url.split('/').pop()
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    if (code) {
        // .exe替换成code+.exe
        link.download = name.replace(/\.exe$/, '_' + code + '.exe')
    } else {
        link.download = name
    }
    link.click();
}
http://www.dtcms.com/a/122747.html

相关文章:

  • Docker新型容器镜像构建技术,如何正确高效的编写Dockerfile
  • 前端三件套—CSS入门
  • 13_pandas可视化_seaborn
  • 青少年编程与数学 02-016 Python数据结构与算法 10课题、搜索
  • Webstorm 使用搜不到node_modules下的JS内容 TS项目按Ctrl无法跳转到函数实现
  • leetcode刷题日记——验证回文串
  • 算法比赛中常用的数学知识
  • C# Winform 入门(15)之制作二维码和拼接(QR)
  • miniconda安装R语言图文教程(详细步骤)
  • 13. git clone
  • Mysql | 主从复制的工作机制
  • 西电服务器环境配置问题汇总(一)
  • 【同步教程】基于Apache SeaTunnel从MySQL同步到MySQL——Demo方舟计划
  • 山东大学软件学院项目实训开发日志(7)之测试前后端本地部署
  • TCP连接四次挥手的过程,为什么是四次?
  • STM32单片机入门学习——第30节: [9-6] FlyMcu串口下载STLINK Utility
  • Rust入门之迭代器(Iterators)
  • 实战篇-梳理时钟树
  • QT学习笔记
  • 使用 DeepSeek API 实现新闻文章地理位置检测与地图可视化
  • 华为手机或平板与电脑实现文件共享
  • 电脑清洁常用工具
  • MySQL:锁
  • 秒杀业务的实现过程
  • Java 开发中主流安全框架的详细对比,涵盖 认证、授权、加密、安全策略 等核心功能,帮助开发者根据需求选择合适的方案
  • IP查询能够帮助企业进行数字化转型
  • 医学分割新标杆!双路径PGM-UNet:CNN+Mamba实现病灶毫厘级捕捉
  • UniApp 页面布局自定义头部导航
  • Seq2Seq - CrossEntropyLoss细节讨论
  • 深入理解 Vuex:核心概念、API 详解与最佳实践