CSS和<input type =“file”/> - 讨论

时间:2010-10-09 01:05:54

标签: javascript html css

我想更改输入的样式和浏览按钮,以便在我的网站上传文件,并且一直在阅读这几乎无法做到的事情。显然有一些黑客可能有效(未经测试),但在我浪费时间之前,我对专业网站似乎没有问题的原因有疑问。

当我说专业时,我的意思是求职网站,你可以上传你的简历,编程网站,你可以上传你的脚本,我的学院网站,我可以上传试卷,政府,医生等。

我看不到他们使用的是某个随机程序员的黑客攻击,可能会也可能不起作用,所以他们正在做什么,因为他们的网站似乎工作和看起来很好?

对此的任何意见都表示赞赏。

由于

Beauford


跟进:

感谢您的投入,但只是给易江的一张纸条 - 您发布的那些肯定会以某种方式呈现。我在我的网站上有一个,并在5个浏览器中查看它,我得到的是基本的方形灰色浏览按钮和方形输入字段,两者之间没有空格,浏览按钮只比输入字段稍微高一点,所以看起来真的很破旧。如果我能让它看起来像你的例子我会欣喜若狂。

由于

3 个答案:

答案 0 :(得分:4)

文件上传字段无法在CSS中设置样式(非常多),也无法从JS编写脚本(足以使代理控件实际工作)。出于这种情况有一些明智的安全理由,尽管你可能会认为它们已经走得太远了。

更一般地说,无论如何都很难设置文件上传字段的样式,因为您不知道文件上载字段是什么样的。这完全取决于浏览器。也许你会在左边看到一个文本字段,右边有一个'浏览'按钮/弹出窗口(在这种情况下,border适用于哪个部分?或两者都有?);也许你只会在左边弹出一个弹出窗口,在右边看一个状态图标/标签(就像在Safari中一样);也许你会得到一个拖放场。或者是其他东西。这完全不受你的控制。

大多数“专业”网站都会执行以下两项操作之一:

  1. 不关心它,只需使用简单的无样式文件上传字段。当您请求上传时,也许在弹出窗口中(所以至少它在屏幕上始终不一致)。

  2. 使用渐进增强技术将HTML文件上传替换为基于Flash的替代上传器(或者不太常见的Java或Silverlight;将来我们将有更多的浏览器支持HTML5拖放 - 和 - 降)。

  3. 有一个详细的here黑客通过使真正的文件上传控件不可见并将其定位在可设置的显示控件的顶部而起作用。但它确实非常不可靠,取决于猜测浏览器的文件上传控制的大小以及响应点击的位数。它对可访问性有害(不能正确响应键盘),对可用性不利(它甚至不能在我完全正常的Firefox上排队)和我不建议使用它。< / p>

答案 1 :(得分:3)

嗯,首先这些黑客不仅仅来自任何一个随机程序员。例如,This one from quirksmode来自一个备受推崇的来源 ,据我所知,广泛使用(这里用于图像上传对话框)。另一个例子是为ajax upload script创建的这个例子。完全忽略Javascript,您可以看到该按钮纯粹是input type="file"卡在div内。

然而,值得注意的是,那里没有你不能忍受的东西。即使是大型网站也使用普通的,无格式的文件输入。这是来自Hotmail

alt text

这是来自GMail

alt text

答案 2 :(得分:0)

在这个帖子中发帖,因为它过时了,过时了,因为其他人(比如我)可能会从谷歌那里找到它,并想知道他们可以做些什么来创建更好看的输入[type = file]框!

简短的回答仍然是:你不能。

但是,如果您准备使用一点JavaScript,那么您实际上可以很好地制作可以设计样式的内容,然后适当地控制文件输入。

首先,HTML沿着以下几行:

<a href="#" class="btn btn-upload">Choose your photo</a>
<div class="fileupload">
    <label for="picture">Your Image:</label>
    <input type='file' name="picture" id="picture" enctype = "multipart/form-data" runat="server" required />
</div>

这允许您使用fileupload div来“隐藏”真实控件 - 但是,不应该使用display:none - 许多浏览器会将此视为安全性风险。相反,请position:relativeleft:-99999px一起使用,或height:0pxoverflow:hidden一起使用。如果您因任何原因需要关闭它(例如需要支持真正的旧IE),那么您可以使用IE样式表或Modernizr并反转css以显示正常上传并隐藏您的“假”。

现在,适当地设置btn-upload样式。但是你想要它。

当有人点击你的'假'时,使用JavaScript为你点击输入文件(以下假设你使用jQuery):

    $(".btn-upload").click(function () {
        $(".fileupload input").trigger('click');
        return false;
    });

此外,如果您想要更改样式文件输入伪装的外观,或者在用户选择文件时让您的页面以任何方式做出反应,您可以使用更改事件来执行此操作。以下示例将在id为image-preview的img标记中显示用户即将上传的图像(这将在10以下的IE中无效):

    $('input[type=file]').change(function () {
        var input = $(this);
        if (input[0].files && input[0].files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                $('#image-preview')
                       .attr('src', e.target.result);
            };

            reader.readAsDataURL(input[0].files[0]);
        }
    });

如果您想使用javascript在某处显示文件,也可以访问文件名:

$('input[type=file]').change(function () {
    var input = $(this);
    if (input[0].files && input[0].files[0]) {
        var file = input[0].files[0]
        if (file) {
           //Put the file name into a div with the id of 'filename'
           $('#filename').html(file.name);
        }

    }
});

使用所有这些,你可以制作一个非常好的上传按钮,看起来非常好,仍然有效。我还建议使用功能检测并在不支持文件上传的浏览器中隐藏所有这些内容(查看你,老IOS!)

文件上传功能检测示例:

function checkForInputFile() {
    var elem = document.createElement("input");
    elem.type = "file";
    if (elem.disabled) return false;
    try {
        elem.value = "Test"; // Throws error if type=file is implemented
        return elem.value != "Test";
    } catch(e) {
        return elem.type == "file";
    }
}

if(checkForInputFile()){
    console.log('i support file input type!');
} else {
    console.log('i dont :(');
}

(以上是基于正确的答案:Detect if <input type="file" /> is supported

最后,如果我们想要一个按钮来清除文件类型输入怎么办?好吧,再次,出于安全考虑,这并不容易。但它有可能!这个解决方案是我最喜欢的:Clearing <input type='file' /> using jQuery

如果你懒得打开链接,这里有一个例子,使用我的示例html,假设我们在页面的某处添加了一个id为remove-file的链接:

function resetFormInputElement(e){
    e.wrap('<form>').closest('form').get(0).reset();
    e.unwrap();
}
$('a#remove-file').click(function () {
    //Clear input file
    resetFormInputElement($('.fileupload input'));
    return false;
});