Me and a guy from work are working on a web application for 开发者_如何学Goour clients to log on and manage there details. One of the sections asks the user to upload there company logo but as we all know the html browes button or the tag as its also known is a hard cookie to style. this is how I want it to look:
But the reality is if I put a plain old file tag in there it would look bland, generic and out of place so I Googled for the solution and after a it of hunting I came across this code which yielded the image below the code (Which I also show the file upload without the opacity set to zero):
#divinputfile
{
height:85px;
width:250px;
margin:0px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
#divinputfile #filepc
{
opacity: 0.0;
-moz-opacity: 0.0;
filter: alpha(opacity=00);
font-size:16px;
cursor: pointer;
}
#filepc
{
margin-top: 12px;
}
#fakeinputfile
{
margin-top:-28px;
}
#fakeinputfile #fakefilepc
{
width:250px;
height:22px;
font-size:18px;
font-family:Arial;
}
<body>
<br />
<div id="divinputfile">
<div id="fakeinputfile">
<br />
<input name="fakefilepc" type="text" id="fakefilepc" />
</div>
<div align="right">
<input name="filepc" type="file" size="1" id="filepc" onchange="document.getElementById('fakefilepc').value = this.value;"/>
</div>
</div>
</body>
This is a basic hack and when I select the styled button I'm really selecting the invisible upload button, then the value of the upload is passed into the test box above to look like its really part of the upload. Two problem with this method and I hoping you'll be able to help me here is
a) Only the button can be click to upload. In most browsers(not including Chrome) you can click into the text box as well as the button to upload the image. Sure with this method the text of the file path is added to the textbox but any alteration to that box wont change the file eg: if you selected file1.jpg to upload but you really wanted file2.jpg, changing the file path in the textbox wont change a thing to the ACTUAL upload element
b) Some browers like Chrome and Opera add the \fakepath\ filepath to the textbox and this is just ugly, so any if statement that can strip this out also would be hugely useful.
Hope you guys can help me with this, if not via code hints then if anyone knows a good JavaScript plug that saves the day.
Thanks
You already have javascript for the textbox to display the new filepath value on change. That’s where you will have to also remove any /fakepath/ parts etc.
You can also add a click event to the text-box which will activate the file-browse click event.
I can instantly tell you that’s rather easy with jQuery, but I don’t know how one would do it with plain JS.
/e: In fact, it seems file-input actions can not be triggered. See related question In JavaScript can I make a "click" event fire programmatically for a file input element?
Question a: No firing the click event. Security and all that. You could add a second invisible upload button just like the first. If one changes, clear out the other. And the hacks pile up...
Question b: See Kissaki's answer. You'll need some JS to clear out that 2nd invisible field anyhow...
Here is a solution.
- Question A is solved by making the
<input type="file" />
the full size of your widget, and using divisions to create non-clickable areas. - Question B is solved using the trick I found here
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Style the File Upload Input - Example</title>
<style type="text/css">
#file-upload {
position:relative;
top:0px;
left:0px;
width:250px;
height:65px;
overflow:hidden;
padding-top:15px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
#file-upload input[type='file'] {
width:250px;
height:65px;
font-size:65px;
opacity:0;
filter:alpha(opacity=0);
position:absolute;
top:15px;
left:0px;
z-index:9;
}
#file-upload input {
width:97%;
}
#file-upload #no-click {
position:absolute;
bottom:0px;
left:0px;
z-index:10;
width:125px;
height:40px;
}
</style>
</head>
<body>
<div id="file-upload">
<input size="0" name="filepc" type="file" id="filepc" onchange="var clone = this.cloneNode(true);clone.type='text';document.getElementById('fakefilepc').value = clone.value?clone.value:this.value;" />
<div id="fake-file-upload">
<input name="fakefilepc" type="text" id="fakefilepc" />
<div id="no-click"></div>
</div>
</div>
</body>
You might want to worry about graceful degradation... here's the same with the HTML, CSS and JavaScript more cleanly separated which should degrade cleanly.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Style the File Upload Input - Example</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("body").addClass("js");
$("#file-upload").append("<div id=\"fake-file-upload\">" +
"<input name=\"fakefilepc\" type=\"text\" id=\"fakefilepc\" />" +
"<div id=\"no-click\"></div>" +
"</div>");
$("#file-upload input[type='file']").change(function() {
var clone = this.cloneNode(true);
clone.type='text';
document.getElementById('fakefilepc').value = clone.value?clone.value:this.value;
});
});
</script>
<style type="text/css">
#file-upload {
position:relative;
top:0px;
left:0px;
width:250px;
height:65px;
}
body.js #file-upload {
overflow:hidden;
padding-top:15px;
background-image: url(images/upload_file.gif);
background-repeat: no-repeat;
background-position: right bottom;
}
body.js #file-upload input[type='file'] {
width:250px;
height:65px;
font-size:65px;
opacity:0;
filter:alpha(opacity=0);
position:absolute;
top:15px;
left:0px;
z-index:9;
}
body.js #file-upload input {
width:97%;
}
body.js #file-upload #no-click {
position:absolute;
bottom:0px;
left:0px;
z-index:10;
width:125px;
height:40px;
}
</style>
</head>
<body>
<div id="file-upload">
<input size="0" name="filepc" type="file" id="filepc" />
</div>
</body>
I was using the following image as the image images/upload_file.gif
(and its respective dimensions for everything related thereto)
I believe the following link might help you: "Ajax Upload; A file upload script with progress-bar, drag-and-drop". Not really ajax, just a clever use of an iframe. Hope it helps. Code well!
It's tough to do and even tougher to do cross-browser. Webkit (safari/chrome) has a very different way of handling this than the IEs and Mozilla. As shown, you'll end up resorting to a ton of hacks which you'll constantly need to check against each browser as they get released.
One way I've found is to progressively enhance to use a flash plug-in. You only need to check for flash being present and flashblock not blocking the element.
For example: http://www.uploadify.com/demos/ (although this doesn't seem to check for flashblock!)
精彩评论