Problem
In a Web site may be my input box below the following:
The designer might want to make the upload part like this and then add a Select button. But when I want to change the normal input box to the upload box, I can't work at all. There is a big difference between browsers, and it's almost impossible to add styles to the default buttons.
It's hard to be a good design upload box, but it's the most we can do.
Notice that Safari's design is a little different. The Safari team would like to turn off the ability to manually enter files, possibly fearing such an overflow. The disadvantage of this design is that the user cannot cancel the upload file after selecting a file.
Solutions
Reader Michael McGrady invented a nice little trick to solve the problem of adding a style to the upload button. All the solutions on this page were invented by him, I just added position:relative, some annotations and tests, and then turned JavaScript.
No time to use this technique:
I want to be like this after use:
You look better now, don't you?
McGrady's approach is simple and elegant:
1, set a normal <input type="file">
, and then placed in the element containing the Postion:relative property.
2, also in the parent element, add a normal <input> and a picture, give them a style. Give him an absolute position so that this generic input can overlap with <input type= "file" >.
3, then the <input type= "file" > Z-index set to 2, so he can be shown on the normal input.
4, finally the <input type= "file" > Opacity set to 0. So <input type= "file" > is invisible, the following input/image can be revealed, but you can also click the "Browse" button. If the position of the button is above the picture, it looks like the image clicked.
Note that you cannot use Visibility:hidden because a true invisible element is not clickable, and we need an invisible element that can be clicked.
At this point, the effect can be shown through a pure CSS, but it's almost
5, when the user selects a file, the visible fake input box should show the path of the selection file, just like the normal <input type= "file" >. Although it is only necessary to simply copy the contents of the <input type= "file" >, JavaScript is still required.
So this technique, if not JavaScript, may not be fully implemented. I'll explain the reason in a minute. I decided to write the whole idea into JavaScript. If you want to use an upload box without a filename, you can also use a pure CSS method, although this is not a good idea.
HTML/CSS structure
I'm going to use the following HTML/CSS structure:
Copy Code code as follows:
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>
The position of the <div class= "fileinputs" > is relative so that we can place an absolute position inside the layer: a false input box.
<div class= "Fakefile" > contains a fake input box and a button whose position is absolute and the Z-index value is 1 so that he can display it under the real upload box.
The Real upload box also has the position attribute relavtive, so it can set his z-index value. In short, the upload box is displayed above the fake input box. Then we set his transparency to 0, so that he was not visible.
Also note text-align:right: Because Mozilla cannot set the width of the upload box, we have to make sure that the navigation button is on the right edge of the DIV, the fake button is on the right, and it should be underneath.
You will also need some CSS code to set the width height border and so on, in this example I did not write.
Why is JavaScript?
The first reason to use 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 handle CSS, file input in Netscape and IE4 is inaccessible. For browsers that do not have CSS, users will see two of input boxes and cannot understand what the second is.
The problem with Netscape 4
In Netscape 4, users can only see buttons. Maybe it's because of the position:absolute.
The problem of IE4
Inside the IE4 there will be a strange shadow of the original "Browse" button, and cannot be clicked. There's no way out.
The problem with Netscape 3
For browsers that do not have CSS functionality. Although it can be used, two input boxes will make users depressed.
Solution-javascript
The solution to these problems is javascript: generate input boxes and buttons from JavaScript. The worst case scenario is that JavaScript can't do it, even if it does, users can upload files. Although not so good-looking, but still can work.
So the original complex HTML becomes:
Copy Code code as follows:
<div class= "Fileinputs" >
<input type= "File" class= "file" >
</div>
We use JavaScript to add other elements.
Code
Copy Code code as follows:
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;
}
}
}
Explain
If the browser does not support the Web DOM, then do nothing.
Copy Code code as follows:
var w3cdom = (document.createelement && document.getelementsbytagname);
function Initfileuploads () {
if (! W3cdom) return;
Create <div class= "Fakefile" > and his content. We'll copy it when it's needed.
Copy Code code as follows:
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);
All input on the page is then traversed, if not <input type= "file" > is ignored.
Copy Code code as follows:
var x = document.getelementsbytagname (' input ');
for (Var i=0;i<x.length;i++) {
if (x[i].type!= ' file ') continue;
Check again: If <input type= "File" > 's parent element has no fileinputs class, it is ignored.
Copy Code code as follows:
if (x[i].parentnode.classname!= ' fileinputs ') continue;
Now we've found the upload box that needs to be added to the style. First we add a hidden class name.
Copy Code code as follows:
X[i].classname = ' file hidden ';
Copy the fake input box and add it to the parent element of <input type= "file" >.
Copy Code code as follows:
var clone = Fakefileupload.clonenode (true);
X[i].parentnode.appendchild (clone);
Now we have successfully added the style. But it's not over yet, we want the user to see the file path in the input box.
First we give <input type= "file" > Create a property that points to the fake input box:
Copy Code code as follows:
X[i].relatedelement = clone.getelementsbytagname (' input ') [0];
So when the user changes the upload file, we can easily and timely access to the fake input box, and then copy the path.
There's a problem here, what event do we use? The change event is usually used, and the value of the fake input box changes as the upload file changes.
But Mozilla 1.6 does not support this event on the upload box (Firefox support). So I'm here to add a onmouseout event. (ie can also run, Safari not)
Copy Code code as follows:
X[i].onchange = X[i].onmouseout = function () {
This.relatedElement.value = This.value; 3}
Issues and Extensions
There is also a problem, the user has chosen a file can not be canceled.
Suppose the user chooses a file and then suddenly doesn't want to upload it. Usually you just need to delete the file path. But in our case it's hard to try and delete it but it's usually the opposite of what you feel.
So we want the user to modify the real upload path by modifying the fake input box.
It is possible to allow choices. When the user selects any part of the uploaded file, we select the entire contents of the fake input box.
[Code] X[i].onselect = function () {2 this.relatedElement.select (); 3}
But JavaScript security does not allow the program to modify the upload path, so we can't modify the actual upload path by letting the user modify the contents of the input box. So I decided to give up the Onselect incident.
One possible way to do this is to add a clear button to the Release input box, delete the original upload box after the user clicks and recreate one. This is cumbersome, but it does remove the file path that users do not want to upload. I don't think this is going to work, and I'm not writing this part of the code.
Click the path of the event
Some readers suggest, remove those miscellaneous CSS, completely hide the upload box, and then the fake input box click event bound to the real upload box. It's a great idea, and it's much simpler than the above.
[Code] Fakefield.onclick = function () {2 Realfield.click () 3}
This click () method allows you to simulate a form item. check box click, the Radio box is selected, and so on. However, Mozilla and opera do not support it. I want to know why, because the most unsafe way to add this method is to pop up a dialog box that selects the file.
So we can not use this simple method.
Translation Address: http://www.quirksmode.org/dom/inputfile.html
Reprint please keep the following information
Author: North Jade (TW: @rehawk)