[Translation] JavaScript CSS Modification Study Chapter 5: Add a style for "Upload"

Source: Internet
Author: User
Document directory
  • Netscape 4 Problems
  • Ie4 Problems
  • Netscape 3 Problems
  • Solution-Javascript
  • Explanation
  • Click Event path

In all form items, the file upload part is the most difficult to add styles. IE supports some (not many) style attributes, few Mozilla, and few other browsers. The "Browse" button is also difficult to access in CSS operations.

Problem

In a website, my input box may be as follows:

The designer may want to make the upload part look like this and then add a select button. However, when I want to change a normal input box to an upload box, it will not work at all. There are many differences between browsers, and it is almost impossible to add styles to the default buttons.

This is difficult to become a well-designed upload box, but it is also the most we can do.

Note that safari is designed differently. The safari team may worry about this overflow if they want to disable the manual file input function. The disadvantage of this design is that you cannot cancel uploading a file after selecting a file.

 

Solution

Reader Michael McGrady invented a good tips to solve the problem of adding styles to the upload button. He invented all the solutions on this page. I just added position: relative, some comments and tests, and then converted them into JavaScript.

When this technique is not used:

After using it, I want to be like this:

It looks better now, doesn't it?

The McGrady method is simple and elegant:

1. Set a common<input type="file">And then placed in the element that contains the postion: relative attribute.

2. Add a common <input> and an image to the parent element and set the style for them. Set an absolute position for the input to overlap with <input type = "file">.

3. Set the Z-index of <input type = "file"> to 2 so that it can be displayed on a common input.

4. Finally, set the opacity of <input type = "file"> to 0. In this way, the <input type = "file"> is invisible, and the following input/image is displayed, but you can click the "Browse" button. If the button is located on the image, it seems that the image is clicked.

Note that you cannot use visibility: hidden, because a truly invisible element cannot be clicked. We need an invisible element that can be clicked.

So far, this effect can be displayed through pure CSS, but it is still a little worse

5. After you select a file, the visible false input box should display the path of the selected file, just like the normal <input type = "file">. Although you only need to simply copy the content of <input type = "file">, you still need JavaScript.

Therefore, this technology may not be fully implemented without JavaScript. I will explain the reason later. I decided to write the entire idea into JavaScript. If you want to use an upload box without a file name, you can also use the pure CSS method, although this is not a good method.

 

Html/CSS Structure

I plan to use the following html/CSS structure:

div.fileinputs {position: relative;}div.fakefile {position: absolute;top: 0px;left: 0px;z-index: 1;}input.file {position: relative;text-align: right;-moz-opacity:0 ;filter:alpha(opacity: 0);opacity: 0;z-index: 2;}<div class="fileinputs"><input type="file" class="file" /><div class="fakefile"><input /></div></div>

 

<Div class = "fileinputs"> The position is relative, so that we can place an absolute layer in it: a false input box.

<div class="fakefile">Contains a false input box and a button. Its position is absolute and the Z-index value is 1, so that it can be displayed under the real upload box.

The real upload box also has the location attribute relavtive, so that you can set its Z-index value. In short, the upload box must be displayed on a false input box. Then we set the transparency to 0 to make it invisible.

Note that text-align: Right: Because Mozilla cannot set the width of the upload box, make sure that the Browse button is on the right edge of the DIV and the fake button is on the right, and it should be true.

You also need some CSS code to set the width and height of the border and so on. In this example, I did not write it.

 

Why JavaScript?

The first reason for using JavaScript is to copy the file path to a fake text box.

Second, JavaScript ignores meaningless HTML code:<div class="fakefile">To keep the code clean.

Finally, for some old browsers that cannot process CSS, file input in Netscape and ie4 is not accessible. For Browsers without CSS, users will see two input boxes and cannot understand what the second one is.

Netscape 4 Problems

In Netscape 4, you can only see the button. It may be because of position: absolute.

Ie4 Problems

In ie4, there will be a strange "Browse" button shadow, and you cannot click it. No solution

Netscape 3 Problems

For browsers that do not have the CSS function. Although it can be used, two input boxes will make the user depressed.

Solution-Javascript

The solution to these problems is javascript: generate input boxes and buttons through JavaScript. The worst case is that JavaScript cannot be executed. Even so, users can upload files. Although not so nice, it can still work.

So the complex HTML turns:

<div class="fileinputs"><input type="file" class="file"></div>

We use JavaScript to add other elements.

 

Code
var W3CDOM = (document.createElement && document.getElementsByTagName);function initFileUploads() {if (!W3CDOM) return;var fakeFileUpload = document.createElement('div');fakeFileUpload.className = 'fakefile';fakeFileUpload.appendChild(document.createElement('input'));var image = document.createElement('img');image.src='pix/button_select.gif';fakeFileUpload.appendChild(image);var x = document.getElementsByTagName('input');for (var i=0;i<x.length;i++) {if (x[i].type != 'file') continue;if (x[i].parentNode.className != 'fileinputs') continue;x[i].className = 'file hidden';var clone = fakeFileUpload.cloneNode(true);x[i].parentNode.appendChild(clone);x[i].relatedElement = clone.getElementsByTagName('input')[0];x[i].onchange = x[i].onmouseout = function () {this.relatedElement.value = this.value;}}}

Explanation

If the browser does not support W3C Dom, do nothing.

var W3CDOM = (document.createElement && document.getElementsByTagName);function initFileUploads() {if (!W3CDOM) return;

Create <Div class = "fakefile"> and its content. We will copy it as needed.

var fakeFileUpload = document.createElement('div');fakeFileUpload.className = 'fakefile';fakeFileUpload.appendChild(document.createElement('input'));var image = document.createElement('img');image.src='pix/button_select.gif';fakeFileUpload.appendChild(image);

The system then traverses all the inputs on the page. If it is not <input type = "file">, it is ignored.

var x = document.getElementsByTagName('input');for (var i=0;i<x.length;i++) {if (x[i].type != 'file') continue;

Check again: if the parent element of <input type = "file"> does not have a class of fileinputs, ignore it.

if (x[i].parentNode.className != 'fileinputs') continue;

Now we have found the upload box for adding styles. First, add a hidden class name.

x[i].className = 'file hidden';

Copy the false input box and add it to the parent element of <input type = "file">.

var clone = fakeFileUpload.cloneNode(true);x[i].parentNode.appendChild(clone);

Now we have successfully added the style. But it is not over yet. We want the user to see the file path in the input box.

First, create an attribute for <input type = "file"> to point to a false input box:

x[i].relatedElement = clone.getElementsByTagName('input')[0];

In this way, when the user changes the upload file, we can easily and timely access the false input box, and then copy the path.

There is a problem here. What event do we use? Usually, the change event is used. When the uploaded file changes, the value of the false input box also changes.

However, Mozilla 1.6 does not support this event in the upload box (supported by Firefox ). So I will add an onmouseout event here. (Ie can also run, but safari cannot)

x[i].onchange = x[i].onmouseout = function () {this.relatedElement.value = this.value;}

 

 

Problems and extensions

Another problem is that the user cannot cancel a file after selecting it.

Assume that the user selects a file and suddenly does not want to upload it. Generally, you only need to delete the file path. However, in our example, it is very difficult. You can try it and delete it, but it is usually the opposite.

Therefore, we hope that you can modify the real upload path through the fake input box.

It is possible to allow selection. When you select any part of the uploaded file, we select all the contents in the entire false input box.

x[i].onselect = function () {this.relatedElement.select();}

However, JavaScript Security does not allow the program to modify the upload path, so we cannot modify the real upload path by asking the user to modify the content of the input box. So I decided to discard the onselect event.

A feasible method is to add a clear button to the fake input box. After the user clicks the button, the original upload box is deleted and a new one is created. This is cumbersome, but it can delete the file path that the user does not want to upload. I don't think this can work, And I didn't write this part of code.

Click Event path

Some readers suggest removing the complicated CSS, hiding the upload box completely, and binding the Click Event of the fake input box to the real upload box. Great idea, and much simpler than above.

fakeField.onclick = function () {realField.click()}

This click () method allows you to simulate a form item. Click the check box, and select a single region. However, Mozilla and opera do not. I want to know why, because the biggest insecure way to add this method is to bring up a dialog box for selecting files.

Therefore, we cannot use this simple method.

 

Http://www.quirksmode.org/dom/inputfile.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.