Downloader JS File

need library js-file-downloader

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/485684/1317487/Downloader%20JS%20File.js

  1. class Downloader {
  2. MAX_DOWNLOAD = 5;
  3. PAUSE_TIME = 1000;
  4. progress = 0;
  5. status = false
  6.  
  7. constructor({ pause } = {}) {
  8. if(jsFileDownloader === undefined) {
  9. throw new Error("Can't make instance");
  10. }
  11. if(pause) this.PAUSE_TIME = pause;
  12.  
  13. let css = document.createElement("style");
  14. css.innerText = `.downloader-container{background-color:#2f4f4f;width:calc(100% - 12px);max-width:520px;min-height:64px;position:fixed;bottom:10px;left:50%;transform:translateX(-50%);border-radius:8px;padding:.5em .75em;box-shadow:3px 4px 11px 0 #0000003b}.downloader-container .header{display:flex;justify-content:space-between;align-items:center;padding-bottom:.5em;border-bottom:1px solid #e2e2e259}.downloader-container .header h4{font-size:1.25em}.downloader-container .body{padding:.75em 0}.downloader-container .body ul{list-style-type:none;display:flex;flex-direction:column;gap:.25em}.downloader-container .body .file-item{display:flex;justify-content:space-between;gap:4px;background-color:#fff;padding:.25em;border-radius:4px}.downloader-container .body .file-item p{font-size:1em}`;
  15. document.head.append(css);
  16.  
  17. this.urls = []
  18. this.__makeContainer();
  19. this.__makeHeader();
  20. this.__makeBody();
  21. }
  22.  
  23. __makeContainer() {
  24. this._container = document.createElement("div");
  25. this._container.classList.add("downloader-container")
  26. }
  27.  
  28. __makeHeader() {
  29. this._header = document.createElement("div");
  30. this._header.classList.add("header");
  31. let title = document.createElement("h4");
  32. title.innerText = "Downloader";
  33.  
  34. this._count_files = document.createElement("p");
  35. this._count_files.addEventListener("update", (e) => {
  36. const { current, total } = e.detail;
  37. this._count_files.innerText = `${current}/${total}`;
  38. })
  39. this.updateProgress(0);
  40. this._header.append(title, this._count_files);
  41.  
  42. this._container.append(this._header);
  43. }
  44.  
  45. __makeBody() {
  46. let body = document.createElement("div");
  47. body.classList.add("body");
  48.  
  49. this.__containerItem = document.createElement("ul");
  50. this.__containerItem.classList.add("files-containter")
  51.  
  52. body.append(this.__containerItem);
  53.  
  54. this._container.append(body);
  55. }
  56.  
  57. __makeItem(title) {
  58. const item = document.createElement("li");
  59. item.classList.add("file-item");
  60.  
  61. const titleContainer = document.createElement("p");
  62. titleContainer.innerText = title;
  63.  
  64. const progress = document.createElement("span");
  65. progress.innerText = "0%"
  66.  
  67. item.append(titleContainer, progress);
  68.  
  69. function updateProgress(percent) {
  70. progress.innerText = `${percent} %`
  71. }
  72.  
  73. return {
  74. item,
  75. updateProgress,
  76. }
  77. }
  78.  
  79. add_url(url, { title } = {}) {
  80. if(title === undefined) {
  81. title = `File - ${this.urls.length}`;
  82. }
  83. this.urls.push({ url, title })
  84. this.updateProgress(0)
  85. }
  86.  
  87. add_urls(urls) {
  88. for(const item of urls) {
  89. add_url(item.url)
  90. }
  91. }
  92.  
  93. async __download(url, title) {
  94. const downloadContainer = document.createElement("li")
  95. const progressFile = this.__makeItem(title || "File");
  96. this.__containerItem.append(progressFile.item);
  97. const process = (event) => {
  98. if (!event.lengthComputable) return; // guard
  99.  
  100. var downloadingPercentage = Math.floor(event.loaded / event.total * 100);
  101. console.log(downloadingPercentage)
  102. progressFile.updateProgress(downloadingPercentage)
  103. };
  104.  
  105. new jsFileDownloader({ url, process })
  106. .then(async () => {
  107. progressFile.updateProgress(100);
  108. await new Promise(res => setTimeout(() => res(), 500));
  109. progressFile.item.remove();
  110. Promise.resolve(true)
  111. })
  112. .catch(err => Promise.reject(err))
  113. }
  114.  
  115.  
  116. async start() {
  117. if(this.status) return;
  118.  
  119. this.progress = 0
  120. this.updateProgress(this.progress);
  121. document.body.append(this._container);
  122. this.status = true;
  123.  
  124. let countProgress = 0;
  125. for(const [key, item] of Object.entries(this.urls)) {
  126. this.__download(item.url)
  127. .then(async () => {
  128. this.progress += 1;
  129. this.updateProgress(this.progress);
  130. countProgress -= 1
  131. })
  132. .catch(e => {
  133. countProgress -= 1
  134. console.error(e)
  135. })
  136. countProgress += 1;
  137.  
  138. while(true) {
  139. if(countProgress <= 5) break
  140.  
  141. await new Promise(res => setTimeout(() => res(), this.PAUSE_TIME))
  142. }
  143.  
  144. console.log("Progress " + key)
  145. }
  146. }
  147.  
  148. updateProgress(current) {
  149. const event = new CustomEvent("update", { detail: { current, total: this.urls.length }});
  150. this._count_files.dispatchEvent(event);
  151. }
  152. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址