大綱

主程式分兩部分,擷取PDF成網頁(函數:getlink()) 然後下載(函數:dogetfile)。

資料夾 下載連結 大小 / byte:
appDownload.js 961
appDownload_2.js 1010
appDownload_Note.files
testDownload.html 1426
testDownload.html 1426
testDownload.js 394

參考

多檔下載為zip

檔案說明

主要是測試appDownload.js 目標是: 將對象網頁中的PDF檔案,列在文件中,然後一一存檔。

appDownload.js

在snippet 中執行。

原始碼(appDownload.js)
var app, adoc;
async function getlink()
//將目前網頁中的PDF連結,抽出來成為另一個文件
{
    var allLinks = document.links;
    for (var i=0; i<allLinks.length; i++) {
        if(/\.pdf$/g.test(allLinks[i].href)){
           var ele = adoc.createElement("a")
           var s=allLinks[i].href;
           ele.href=s;
           var fname = s.substr(s.lastIndexOf("/")+1)
           ele.innerHTML=fname;
           ele.download=fname;
           ele.target="_blank";//★
           adoc.body.appendChild(ele);
           //adoc.body.appendChild(adoc.CreateElement("br"));
        }
      
    }
}

function dogetfile()
{
    var lks = adoc.links;
    console.log("total:  "+ adoc.length)
    for(i=0;i<lks.length;i++)
    {
     lks[i].click()  ;
    }
}
app=window.open(); //open 裡面如果有東西,會跟目前文件的伺服器要求,當然會拿不到。
adoc=app.document;
getlink(adoc).then(dogetfile)

Note:

  1. 如果沒有第14行 ( ele.target="_blank";) ,就只能下載一個
  2. 因為這裡的連結<a>直接顯示在文件上,所以直接呼叫click()就可以。否則,還是必須用前面討論 的方法,利用dispatchEvent。例如只是嵌入我們自己的連結到其他主站的網頁,就不必顯示,此時click()函數會無法作用。(理論上,待測)。
  3. 這裡用到了async 因為js是non-blocking 語言。所以等待所有link都抓完,才下載檔案。

小測試

利用程式碼中的getLInk() 把google 關鍵字javascript ptf 的搜尋結果存成testDownload.html,

testDownload.html 的內容如下:

<a href="https://eloquentjavascript.net/Eloquent_JavaScript.pdf" download="Eloquent_JavaScript.pdf">Eloquent_JavaScript.pdf</a>
<!-- 只列出一個連結 -->
<script src="testDownload.js"> </script>

然後利用之下的的程式碼測試多個檔案下載

testDownload.js

js
function domulti()
{
    
function getNext(i) {
    if (i >= lks.length) {
      return;
    }
    console.log("I am (" +i+") [" + lks[i].download+"]")
    lks[i].target="_blank";
    lks[i].click();
    setTimeout(function() {
      getNext(i+1);
    }, 500);

  // Initiate the first download.
  //getNext(i+1);
}
getNext(0);
}

    lks = document.links;
    domulti();

non-block

預計每隔三秒打招呼



alert('hi');

for(var start = 1; start < 10; start++) {
  setTimeout(function () {
    alert('hello');
  }, 3000);
}
 

更正

var i = 1;                     //  set your counter to 1

function myLoop () {           //  create a loop function
   setTimeout(function () {    //  call a 3s setTimeout when the loop is called
      alert('hello');          //  your code here
      i++;                     //  increment the counter
      if (i < 10) {            //  if the counter < 10, call the loop function
         myLoop();             //  ..  again which will trigger another 
      }                        //  ..  setTimeout()
   }, 3000)
}

myLoop();   

也就是在每一次的myloop中,又設定下一次的myloop

如果利用closure

(function myLoop (i) {          
   setTimeout(function () {   
      alert('hello');          //  your code here                
      if (--i) myLoop(i);      //  decrement i and call myLoop again if i > 0
   }, 3000)
})(10);