Muat naik fail sangat mudah didapati di mana-mana aplikasi web dan apabila memuat naik fail dan sumber melalui Internet (pada penyemak imbas), perkara boleh menjadi agak tertekan. Nasib baik, dengan HTML 5, elemen input yang biasanya disertakan dengan kawalan borang untuk membolehkan pengguna mengubah suai data boleh menjadi sangat berguna dalam memudahkan muat naik sumber.
Dalam artikel ini, kita akan melihat dengan lebih dekat cara mengendalikan muat naik fail menggunakan JavaScript vanila. Matlamatnya adalah untuk mengajar anda cara membina komponen muat naik fail tanpa memerlukan perpustakaan luaran dan juga mempelajari beberapa konsep teras dalam JavaScript. Anda juga akan belajar cara menunjukkan status kemajuan muat naik semasa ia berlaku.
Kod Sumber: Seperti biasa, anda boleh bermain-main dengan kod sumber yang dihoskan pada repo GitHub untuk projek itu.
Pertama sekali, dalam direktori pilihan anda, buat folder baharu untuk projek:
$ mkdir file-upload-progress-bar-javascript
Selepas berbuat demikian, marilah kita mencipta fail index.html, main.css dan app.js di mana kita akan menulis semua penanda untuk projek kita.
$ touch index.html && touch main.css && touch app.js
Kini kita boleh mula membina struktur untuk muat naik fail dengan mencipta templat HTML asas dengan
dan<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>File Upload with Progress Bar using JavaScript</title> </head> <body></body> </html>
Seterusnya, kami menambah gaya asas untuk projek dalam main.css:
* { margin: 0; padding: 0; box-sizing: border-box; }
Untuk meningkatkan rupa aplikasi kami, kami akan menggunakan ikon daripada perpustakaan hebat fon yang boleh kami tambahkan pada projek kami melalui kod kit yang boleh dibuat di tapak web perpustakaan hebat fon rasmi.
Kini, index.html dikemas kini dan fail main.css dipautkan:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script src="https://kit.fontawesome.com/355573397a.js" crossorigin="anonymous" ></script> <link rel="stylesheet" href="main.css"> <title>File Upload with Progress Bar using JavaScript</title> </head> <body></body> </html>
Kami meneruskan dengan membina struktur untuk pemuat naik fail:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <script src="https://kit.fontawesome.com/355573397a.js" crossorigin="anonymous" ></script> <link rel="stylesheet" href="main.css" /> <title>File Upload with Progress Bar using JavaScript</title> </head> <body> <div class="file-upload__wrapper"> <header>File Uploader JavaScript with Progress</header> <div class="form-parent"> <form action="#" class="file-upload__form"> <input class="file-input" type="file" name="file" hidden /> <i class="fas fa-cloud-upload-alt"></i> <p>Browse File to Upload</p> </form> <div> <section class="progress-container"></section> <section class="uploaded-container"></section> </div> </div> </div> <script src="app.js"></script> </body> </html>
Kemudian, salin/tampal kod berikut untuk mengemas kini main.css:
* { margin: 0; padding: 0; box-sizing: border-box; } body { min-height: 100vh; background: #cb67e9; display: flex; align-items: center; justify-content: center; font-family: Arial, Helvetica, sans-serif; } ::selection { color: white; background: #cb67e9; } .file-upload__wrapper { width: 640px; background: #fff; border-radius: 5px; padding: 35px; box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.05); } .file-upload__wrapper header { color: #cb67e9; font-size: 2rem; text-align: center; margin-bottom: 20px; } .form-parent { display: flex; align-items: center; gap: 30px; justify-content: center; } .file-upload__wrapper form.file-upload__form { height: 150px; border: 2px dashed #cb67e9; cursor: pointer; margin: 30px 0; display: flex; align-items: center; flex-direction: column; justify-content: center; border-radius: 6px; padding: 10px; } form.file-upload__form :where(i, p) { color: #cb67e9; } form.file-upload__form i { font-size: 50px; } form.file-upload__form p { font-size: 1rem; margin-top: 15px; } section .row { background: #e9f0ff; margin-bottom: 10px; list-style: none; padding: 15px 12px; display: flex; align-items: center; justify-content: space-between; border-radius: 6px; } section .row i { font-size: 2rem; color: #cb67e9; } section .details span { font-size: 1rem; } .progress-container .row .content-wrapper { margin-left: 15px; width: 100%; } .progress-container .details { display: flex; justify-content: space-between; align-items: center; margin-bottom: 7px; } .progress-container .content .progress-bar-wrapper { height: 10px; width: 100%; margin-bottom: 5px; background: #fff; border-radius: 30px; } .content .progress-bar .progress-wrapper { height: 100%; background: #cb67e9; width: 0%; border-radius: 6px; } .uploaded-container { overflow-y: scroll; max-height: 230px; } .uploaded-container.onprogress { max-height: 160px; } .uploaded-container .row .content-wrapper { display: flex; align-items: center; } .uploaded-container .row .details-wrapper { display: flex; flex-direction: column; margin-left: 15px; } .uploaded-container .row .details-wrapper .name span { color: green; font-size: 10px; } .uploaded-container .row .details-wrapper .file-size { color: #404040; font-size: 11px; }
Kini, komponen sepatutnya kelihatan lebih baik pada penyemak imbas:
Untuk menambah fungsi yang diperlukan untuk memuat naik dalam projek kami, kami kini menggunakan fail app.js, tempat kami menulis kod JavaScript yang menghidupkan projek kami.
Salin/tampal yang berikut ke dalam app.js:
const uploadForm = document.querySelector(".file-upload__form"); const myInput = document.querySelector(".file-input"); const progressContainer = document.querySelector(".progress-container"); const uploadedContainer = document.querySelector(".uploaded-container"); uploadForm.addEventListener("click", () => { myInput.click(); }); myInput.onchange = ({ target }) => { let file = target.files[0]; if (file) { let fileName = file.name; if (fileName.length >= 12) { let splitName = fileName.split("."); fileName = splitName[0].substring(0, 13) + "... ." + splitName[1]; } uploadFile(fileName); } }; function uploadFile(name) { let xhrRequest = new XMLHttpRequest(); const endpoint = "uploadFile.php"; xhrRequest.open("POST", endpoint); xhrRequest.upload.addEventListener("progress", ({ loaded, total }) => { let fileLoaded = Math.floor((loaded / total) * 100); let fileTotal = Math.floor(total / 1000); let fileSize; fileTotal < 1024 ? (fileSize = fileTotal + " KB") : (fileSize = (loaded / (1024 * 1024)).toFixed(2) + " MB"); let progressMarkup = `<li class="row"> <i class="fas fa-file-alt"></i> <div class="content-wrapper"> <div class="details-wrapper"> <span class="name">${name} | <span>Uploading</span></span> <span class="percent">${fileLoaded}%</span> </div> <div class="progress-bar-wrapper"> <div class="progress-wrapper" style="width: ${fileLoaded}%"></div> </div> </div> </li>`; uploadedContainer.classList.add("onprogress"); progressContainer.innerHTML = progressMarkup; if (loaded == total) { progressContainer.innerHTML = ""; let uploadedMarkup = `<li class="row"> <div class="content-wrapper upload"> <i class="fas fa-file-alt"></i> <div class="details-wrapper"> <span class="name">${name} | <span>Uploaded</span></span> <span class="file-size">${fileSize}</span> </div> </div> </li>`; uploadedContainer.classList.remove("onprogress"); uploadedContainer.insertAdjacentHTML("afterbegin", uploadedMarkup); } }); let data = new FormData(uploadForm); xhrRequest.send(data); }
Apa yang telah kami lakukan ialah dapat membaca fail yang telah dipilih daripada menggunakan elemen input fail dan mencipta senarai fail baharu pada DOM. Apabila fail sedang dimuat naik, tahap kemajuan ditunjukkan dan apabila fail selesai dimuat naik, status kemajuan berubah kepada dimuat naik.
Kemudian, kami juga menambah uploadFile.php pada projek kami untuk mengejek titik akhir untuk menghantar fail. Sebabnya adalah untuk mensimulasikan ketidaksegerakan dalam projek kami supaya kami mendapat kesan pemuatan kemajuan.
<?php $file_name = $_FILES['file']['name']; $tmp_name = $_FILES['file']['tmp_name']; $file_up_name = time().$file_name; move_uploaded_file($tmp_name, "files/".$file_up_name); ?>
Anda hebat untuk sampai ke tahap artikel ini.
Dalam tutorial ini, anda telah mempelajari cara membina komponen muat naik fail dan menambah bar kemajuan padanya. Ini boleh berguna apabila anda membina tapak web dan mahu pengguna anda berasa disertakan dan memahami betapa lambat atau pantasnya memuat naik fail berjalan. Jangan ragu untuk menggunakan semula projek ini pada bila-bila masa anda mahu.
Jika anda buntu semasa mengikuti tutorial ini, saya cadangkan anda memuat naik projek anda di GitHub untuk mendapatkan bantuan daripada pembangun lain atau anda juga boleh menghantar dm kepada saya juga, saya akan berbesar hati membantu.
Berikut ialah pautan ke repo GitHub untuk projek itu.
Atas ialah kandungan terperinci Cara Muat Naik Fail Dengan JavaScript Vanila dan Tambah Animasi Memuatkan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!