检测<input type="file" />是否被支持

23

我正在构建我的网站的移动版本,其中包含一个文件上传功能,可以通过“上传按钮”访问

我希望隐藏这个按钮对于iPhone用户来说,因为该控件看起来只是灰色的 - 这可能吗?

我不想检测iPhone; 我觉得检测功能会更好 - 如果苹果启用此功能(或手机越狱等),它将自动开始工作。

7个回答

5

检查是否已实现input[type=file]的功能:

function isInputTypeFileImplemented() {
    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";
    }
}

Fiddle: http://jsfiddle.net/8EqEE/9


我在Firefox和移动Safari上使用它得到了相同的结果吗? - Nasreddine
那是真的吗?如果是真的,input[type=file] 是被支持的,但未被实现。请查看我的更新答案。 - Rob W
返回 true :-( - 甚至尝试将其添加到 DOM 中并等待测试其类型 - Ben Robinson
@Rob:iPhone 返回 false,但 Chrome 也是如此 - elem.value='Test'; 不会抛出错误!input[file=type] 已实现! - Ben Robinson
1
在 iPhone iOS 5 上不起作用,但是可以将 elem.disabled 设置为 true。为了支持iOS,请添加此功能。 - Zymotik
显示剩余3条评论

4

更新:此功能现在已经成为Modernizr的一部分。

现在有一个适用于modernizr的拉取请求,看起来它能够正常工作。它基本上只是检查:

var elem = document.createElement('input');
elem.type = 'file';
return !elem.disabled;

它还检查navigator.userAgent以获取已知会产生误报的某些浏览器。相关代码:https://github.com/Modernizr/Modernizr/blob/master/feature-detects/forms/fileinput.js - Luke

2
创建一个<input type="file">并检查它是否已禁用。
function isFileUploadImpossible() {
    var el = document.createElement("input");
    el.setAttribute("type", "file");
    return el.disabled;
}

在 iOS 4.2.1、Android 2.3.4、Chrome 17、Firefox 11 和 IE7 上进行了测试。


你的意思是WP7错误地将其input[type="file"]报告为禁用吗? - jayarjo

0
请注意,我还没有测试过这个,所以不确定它是否有效。这基本上是测试对HTML5输入类型(例如<input type="color" />)的支持的方法。但你可以试一下:
function upload_supported() {
  var file_input = document.createElement("input");
  file_input.setAttribute("type", "file");
  return file_input.type !== "text";
}

这是基于浏览器的行为,当它遇到未知的输入类型时,会将类型属性重置为text。然而,由于您说它看起来变灰,这意味着它并不是未知的。


0
一个基于值的错误检查(try/catch)加上对禁用状态的检查的混合似乎在我们测试的所有PC和移动浏览器上提供了良好的覆盖率。
alert((function isInputTypeFileImplemented(){
  var elem;
  try {
    elem = document.createElement("input");
    elem.type = "file";
  } catch(e) {
    return -1; // type=file is not implemented  
  }
  try {
    elem.value = "Test";
    if (elem.value == "Test") {
      return -2; // type=file should throw an error on line above
    } else {
      if (elem.disabled) {
        return -3; // type=file disabled in iOS < 6
      } else {
        return true;
      }
    }
  } catch(e){
    return true; // type=file implemented correctly
  }
})())

注意:如果您喜欢不同的流程,可以改变逻辑顺序。

代码演示:http://jsfiddle.net/BRk5J/


0

更新Rob W的解决方案,支持iOS 5 + iOS 6 Beta。 (我不建议引发异常,但这可以解决问题):

     function isInputTypeFileImplemented(){
        var elem = document.createElement("input");
        elem.type = "file";
        try {
            elem.value = "Test"; //If type=file is implemented, this would throw an 
            if (elem.disabled) {
                return false;
            } else {
                return true;
            }
        } catch(e){
            return false;
        }
    }

-1

我也一直在寻找解决这个问题的方法。它并不像已经提出的解决方案那么简单。一些浏览器声称支持某些类型,但由于不完整性,其中一些类型已被禁用。因此,当您返回InputElement.type时,它可能会返回“file”类型或“tel”或“number”,但浏览器仍将其视为“text”。不幸的是,除非您能说服浏览器开发人员修复已禁用的类型以返回文本,否则我认为您目前无法做到这一点。

另外需要注意的是,IE将所有不支持的类型都返回为文本。我已经测试了最新版本的Chrome和FF。Chrome“欺骗”了对数字、电话类型的支持,而FF在不支持时也返回电话。我相信其他类型也会发生这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接