+8

[Tips] Upload File "thần thánh" - Bạn đã biết hết những tips này chưa?

Xin chào các bạn,

Hiện nay, trên các trang mạng xã hội cũng như trong quá trình làm việc, việc bạn phải upload một file hay nhiều file bằng nhiều hình thức khác nhau lên website là một việc rất thường xuyên phải sử dụng. Vậy, bạn có từng tò mò muốn biết cách để có thể upload file bằng cách sử dụng javaScript hay không? Trong bài viết này, mình xin giới thiệu một số tip upload file đơn giản nhưng vô cùng hữu ích dành cho frontend-developer. Chúng ta cùng bắt đầu ngay thôi nào 💪💪

1. Upload file sơ cấp

Tại sao mình gọi là "sơ cấp" bởi vì ngay bản thân nó được coi là cái base, sơ khai cho các tips phía dưới, không có điều kiện phức tạp.

  • Để upload được file, chúng ta cần có điều kiện tiên quyết, là thẻ input có type= "file".
<input type="file" id="file-uploader">

Bằng cách sử dụng loại type này, giao diện người dùng sẽ xuất hiện button cho phép upload 1 hay nhiều file. Nhưng theo mặc định, nó chỉ cho phép chúng ta upload 1 file duy nhất.

  • Đầu tiên, chúng ta khai báo biến fileUploader gán với phần tử có id là file-uploader
const fileUploader = document.getElementById('file-uploader');

Sau đó, thêm sự kiện changeđể đọc file khi file được upload thành công. Tiếp đó, chúng ta sẽ lấy được thông tin của file đã tải lên bằng property event.target.files

fileUploader.addEventListener('change', (event) => {
  const files = event.target.files;
  console.log('files', files);
});

Thử ngó qua demo dưới đây bạn nhé:

2. Multiple file uploads

Để upload multiple file, ta thêm thuộc tính multiple vào file input.

<input type="file" id="file-uploader" multiple />

Cũng giống như ví dụ trước, chúng ta đề cập đến việc upload 1 file đơn, thì sang upload nhiều file, nó hầu như không khác gì cả. Vẫn sử dụng code trên, chúng ta thử console.log('files', files) bạn có nhận thấy, FileList là một obj không? Bạn hiểu ý mình rồi chứ:

Ngó qua demo nhé:

3. Bạn có biết accept property?

Có khi nào bạn đặt câu hỏi, có cách nào để giới hạn loại file mà mình muốn tải lên hay không? Ví dụ như bạn có thể chỉ muốn hiển thị các loại hình ảnh được phép duyệt khi người dùng tải lên ảnh hồ sơ chẳng hạn.

Thì khi đó, chúng ta có một cách vô cùng đơn giản đó là sử dụng thuộc tính accept.

<input type="file" id="file-uploader" accept=".jpg, .png" multiple>

Trong code trên, trình duyệt sẽ chỉ cho phép các file có phần mở rộng là jpg và png thì mới có thể upload file lên được. Khá đơn giản phải không nào, chúng ta cùng xem demo luôn nhé:

4. Quản lý nội dung file

Có phải nhiều khi bạn rất muốn hiển thị nội dung của file có những gì sau khi upload file thành công không? Đối với ảnh hồ sơ, sẽ rất khó hiểu nếu chúng tôi không hiển thị ảnh đã tải lên cho người dùng ngay sau khi tải lên.

Đến đây, chũng ta có thể sử dụng obj FileReaderđể chuyển đổi file sang chuỗi nhị phân. Sau đó, thêm event load để tải chuỗi nhị phân lên file thành công.

// Get the instance of the FileReader
const reader = new FileReader();

fileUploader.addEventListener('change', (event) => {
  const files = event.target.files;
  const file = files[0];

  // Get the file object after upload and read the
  // data as URL binary string
  reader.readAsDataURL(file);

  // Once loaded, do something with the string
  reader.addEventListener('load', (event) => {
    // Here we are creating an image tag and adding
    // an image to it.
    const img = document.createElement('img');
    imageGrid.appendChild(img);
    img.src = event.target.result;
    img.alt = file.name;
  });
});

Hãy thử chọn một file ảnh trong demo bên dưới và xem nó hiển thị như nào bạn nhé:

5. Validate file size

Như các bạn đã thấy, việc đọc dữ liệu kích thước của một file là điều dễ dàng thực hiện, chúng ta thực sự có thể sử dụng nó để xác nhận kích thước file. Bạn có thể cho phép người dùng tải lên tệp hình ảnh có dung lượng tối đa 1MB. Hãy xem chúng ta làm thế nào để thực hiện được điều đó nhé.

// Listener for file upload change event
fileUploader.addEventListener('change', (event) => {
  // Read the file size
  const file = event.target.files[0];
  const size = file.size;

  let msg = '';

 // Check if the file size is bigger than 1MB and prepare a message.
  if (size > 1024 * 1024) {
      msg = `<span style="color:red;">The allowed file size is 1MB. The file you are trying to upload is of ${returnFileSize(size)}</span>`;
  } else {
      msg = `<span style="color:green;"> A ${returnFileSize(size)} file has been uploaded successfully. </span>`;
  }

  // Show the message to the user
  feedback.innerHTML = msg;
});

Cụ thể hơn, chúng ta coi demo nhé. Hãy thử tải lên một file có kích thước khác nhau để xem cách nó hoạt động nhé:

6. Hiển thị tiến trình upload file

Khi bạn muốn tăng trải nghiệm người dùng bằng cách cho phép người dùng có thể dễ dàng nhìn thấy tốc độ tiến trình upload file của họ.

FileReader có một sự kiện khác được gọi là progress để biết số lượng đã được tải là bao nhiêu, đồng thời chúng ta có thể sử dụng thẻ progress của HTML5 để tạo thanh tiến trình.

reader.addEventListener('progress', (event) => {
  if (event.loaded && event.total) {
    // Calculate the percentage completed
    const percent = (event.loaded / event.total) * 100;
    // Set the value to the progress component
    progress.value = percent;
  }
});

Bạn hãy thử tải lên một file có dung lượng lớn và thấy thanh tiến trình hoạt động như nào ở demo bên dưới nhé.

7. Kéo, thả và tải

Hiện nay, việc những trang web không hỗ trợ việc kéo, thả để upload file đã trở thành lỗi thời. Bằng những lợi ích nhanh, tiện của việc kéo thả mà việc sử dụng chúng thành ra rẩt cần thiết. Chúng ta cùng xem làm thế nào để tạo ra điều đó với một vài bước đơn giản dưới đây nhé.

Đầu tiên, hãy tạo vùng thả và tùy chọn một phần để hiển thị nội dung file đã tải lên. Chúng ta sẽ sử dụng một file ảnh để kéo và thả vào đây.

 <div class="vb-content">
    <h1>Drag & Drop an Image</h1>
    <div id="drop-zone">
        DROP HERE
    </div>
    <div id="content">
      Your image to appear here..
    </div>
 </div>

Get dropzone và content theo id tương ứng của chúng.

 const dropZone = document.getElementById('drop-zone');
 const content = document.getElementById('content');

Sau đó thêm sự kiện dragover

dropZone.addEventListener('dragover', event => {
  event.stopPropagation();
  event.preventDefault();
  event.dataTransfer.dropEffect = 'copy';
});

Tiếp theo, xác định những gì chúng ta muốn làm khi hình ảnh bị xóa. Chúng ta sẽ cần một trình nghe sự kiện drop để xử lý điều đó.

dropZone.addEventListener('drop', event => {
  // Get the files
  const files = event.dataTransfer.files;

// Now we can do everything possible to show the
// file content in an HTML element like, DIV
});

Và bây giờ thì hãy thử kéo và thả tệp hình ảnh trong demo bên dưới và xem nó hoạt động như thế nào bạn nhé:

Kết Luận

Thế là đến kết bài rồi, trên đây là một số tips khá hay mà mình có lượm nhặt được về vấn đề upload file "thần thánh". Mong rằng bài viết của mình phần nào đó có thể giúp ích được cho các bạn trong quá trình làm việc. Như thường lệ, hãy cho mình 1 upvote để có thêm động lực ra những bài tiếp theo nhé ! 😆

Xin cảm ơn !


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí