Image uploading is a very common scenario in daily project development. Now various UI frameworks provide their own upload components, and there are a lot of third-party upload components online. You may have been used to working directly with these off-the-shelf components, but didn’t have a deep understanding of their implementation. This article will be simple code, for you to analyze the picture upload each knowledge point.

Style customization

However, the default input-to-label style is not uniform and behaves differently across browsers, so customizing the input style is often required. But the tag is not very friendly to style changes. There are many solutions. The most common is to hide the tag, then associate it with a

    <input type="file" id="uploadImg">
    <label for="uploadImg"> Click upload </label>Copy the code

Image validation

Before uploading, files are generally checked, such as file type, size, format, size, etc.

The file type can be specified by setting accept of the tag. However, the Accept attribute does not completely prevent users from uploading files that are not of the specified type. Therefore, each attribute of the uploaded file can be checked and intercepted. Before verification, we need to obtain the uploaded file through the event object of the change event:

    event.target.files
Copy the code

You can obtain the list of uploaded files. The objects in the list contain the following information:

Thu Apr 19 2018 23:58:35 GMT+0800 {} Name: Thu Apr 19 2018 23:58:35 GMT+0800 {} name:"589adfbfe821c.jpg"
        size: 1357444
        type: "image/jpeg"
        webkitRelativePath: ""
    }
Copy the code

From this object, we can obtain the file size, file type, file name and other information, so that we can verify these information before uploading, so as to intercept illegal files.

However, from the File object, we can’t get the size of the image. In our business, many scenes need to limit the size of uploaded images to a certain fixed value, or to a certain proportion. In order to reduce the late display of the adaptation problem. To verify the size of the uploaded Image, we need to use FileReader and Image.

The FileReader object allows Web applications to asynchronously read files stored on the user’s computer.

The Image() function creates a new HTMLImageElement instance. Its functionality is equivalent to document.createElement(‘img’).

Here, we need to use the readAsDataURL() method of fileReader to read the uploaded file information, and the onload event to get the read file information. As follows:

    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = e => {
        console.log(e.target.result)
    }
Copy the code

In this code, file is the file object in the list of files we obtained earlier. E.target. result indicates that the file content is read.

We then create a new HTMLImageElement instance using the new Image() function and assign the SRC value of the instance to fileReader to read into the file. You get an HTMLImageElement instance of the file, from which you can read the size of the image. The specific code is as follows:

    const image = new Image();
    image.src = e.target.result;
    image.onload = () => {
        console.log(image.width, image.height);
    }
Copy the code

Image upload preview

In the previous development, the image uploading display was usually realized by uploading the file first, displaying the preview image directly and uploading it to the server. However, this could not achieve the purpose of previewing the image before uploading, and many junk images would be uploaded.

Through the previous study for obtaining picture size. I’m sure you can quickly come up with a more elegant way to preview images. Now that we’ve got the HTMLImageElement instance of this file, we’ll append it directly into the Dom container of the page. Or simply set the obtained file to the SRC property of the existing image tag. Uploading previews is that simple.

Picture uploading and uploading progress display

Picture upload, we can directly through the form tag with form submit() method to achieve picture upload. However, we cannot verify and intercept uploaded files before uploading. In addition, the user must actively trigger the submission operation. In order to make our pre-upload blocking work worthwhile, we need to actively trigger the file upload operation at the appropriate time.

Here, we need to use the FormData object to convert the input object data into FormData.

The FormData object is used to compile data into key-value pairs that can be sent using XMLHttpRequest. It is mainly used to send form data, but can also be used to send keyed data independently of the form. If the form encType attribute is set to multipart/form-data, the form’s submit() method is used to send the data, so that the sent data has the same form.

We first create a formData object and then add the fields via the append() method. As follows:

    const formData = new FormData();
    formData.append("file", file);
Copy the code

Note that formData is an object, but console.log does not print out its exact value, only formData {}.

Next, create an XMLHttpRequest object to send the Ajax request. Through the upload.onprogress method of the XMLHttpRequest object, the upload information can be obtained in real time and the upload progress can be further obtained. The specific code is as follows:

    const client = new XMLHttpRequest()
    client.open("POST", uploadUrl)
    client.upload.onprogress = function(e) {
      if (e.lengthComputable) {
        let total = e.total;
        let loaded = e.loaded;
        let percentage = parseFloat(loaded / total).toFixed(2);
      }
    }
    client.send(formData)
Copy the code

In the above code, uploadUrl is the URL to upload. Through the event object of upload.onprogress, you can obtain the size of the uploaded file and the complete file of the current progress. With these two size parameters, you can easily calculate the proportion of uploaded files, and then you can operate freely whether to display the upload progress bar or show the progress data.

Drag and drop to upload

In addition to the traditional click and select file upload, drag-and-drop file upload is also a very common scenario. To use drag-and-drop uploads, you need to use the H5 drag-and-drop methods drop and Drag. In addition to these two main methods, there are several methods triggered by different stages of drag and drop. The commonly used drag and drop methods are as follows:

  • Ondragstart event: an event that is triggered when the dragged element starts to be dragged.
  • Ondrag: Triggers the event repeatedly during an element drag, andtouchmoveThe events are similar. (Object is the dragged element)
  • Ondragend event: an event that is triggered when the drag is complete (on the dragged element)
  • Ondragenter event: an event that is triggered when the drag element enters the target element.
  • Ondragover: an event that is triggered when a drag element is moved on a target element
  • Ondragleave event: an event that is triggered when a drag element is moved on a target element
  • Ondrop: an event that is triggered when the mouse is released over the target element while the element is being dragged.

The events of the drag are similar to the phases of the Touch event. However, it is important to note that each drag event has its own action object, which is divided into ‘dragged element’ and ‘target element’. The dragged element is the Dom element that is dragged, mainly used in the scene where the Dom is dragged and moved within the page. The target element is the element region that receives the dragged element. When the dragged element enters the region, it fires a series of events for the target object.

In the image drag-and-upload business scenario, the dragged elements are image files outside the page, so only the events of the target element are used here. We can use these events to modify the target area style and so on. The two core events are the onDragover and onDrop events. Maybe you think all I need to do is get the file I’m dragging when I release the mouse, so I just need to use the onDrop event? However, due to the default behavior of the browser, the onDrop event is not triggered. Therefore, use e.preventDefault(); To prevent the ondropover browser default event, thus ensuring that the onDrop event is triggered. From the event object of ondrop event, we can get the same file list as event.target.files. The method is event.datatransfer. However, when you’re done, drag and drop and you’ll see that your browser automatically jumps to the preview page for that image. This is also due to the default behavior of the browser, so e.preventDefault() is also used; To block the browser’s default behavior. In this way, the subsequent file verification operation can be carried out. The specific implementation code is as follows:

    <label for="uploadImg"
        onDragOver={e => {
            e.preventDefault();
        }}
        onDrop={e => {
            if(e.dataTransfer) { e.preventDefault(); const file = e.dataTransfer.files[0]; . } }} </label>Copy the code

At this point, the picture upload commonly used knowledge points to comb out, welcome to add.