HTML5表单与Polyfills - 值得吗?

42
尽管html5表单引起了很多关注,但在大多数情况下,采用这种方式会增加额外的工作量。
例如,考虑日期选择器字段。该字段的本地html5实现在每个浏览器中都呈现不同的效果。此外,如果浏览器不支持此功能,则您的polyfill解决方案(例如jquery UI)也会呈现不同的效果。
现在,我们已经为同一表单引入了多个定制和维护点,而我们以前使用jquery时拥有一个完美的工作和统一的解决方案!
我想听听在这个领域的一些真实经验,因为我对这些热门话题感到厌烦!

22
为什么原生的HTML5实现在每个浏览器中呈现不同?唯一会在多个浏览器中查看同一个网站的人是网页设计师。对于可用性来说,重要的是在所有网站中,在一个浏览器中看起来都一样,而不是你的网站在所有浏览器中都完全相同。 - robertc
7
以我的经验来看,设计师和客户往往无法接受这一点。他们都希望在所有浏览器中,这些元素都能非常贴切地与他们的主题相匹配。 - drogon
2
我不确定想要给表单元素一个统一的外观并不会使你成为一个糟糕的设计师。此外,客户通常也希望有相同的东西。我认为我不能也不应该轻易忽略他们的需求。 - drogon
统一在哪里?这只是设计师(也许是客户)关心的事情。 - robertc
17
iOS设备会为日期选择器呈现优美的轮状UI,这肯定比JavaScript能够做到的任何东西都要好得多。大多数移动设备会为电子邮件或数字字段呈现自定义键盘。让设备发挥其最大优势。 - superluminary
2
而且IOS的轮子不起作用;在IOS中,它说支持必填字段,但它们不验证表单,这是持续的头痛! - drogon
3个回答

85

首先我是webshims库的创作者(一个不再维护的polyfill)。回答你的问题:

为一个项目创建表单 polyfill 值得吗?

不值得,仅为了一个项目这样做真的很难。嗯,我已经做过了,只是因为我想使用现代技术。

像 webshims 库这样的表单 polyfill 值得在项目中使用吗?

绝对值得!这里是原因:

1. 美好的标准化声明式 Markup API

在引入 webshims 并编写以下脚本后:

//polyfill forms (constraint validation) and forms-ext (date, range etc.)    
$.webshims.polyfill('forms forms-ext');

您可以将您的小部件和限制条件简单地编写进您的表单中:

<input type="date" />
<input type="date" min="2012-10-11" max="2111-01-01" />
<input type="range" disabled />
<input type="email" required placeholder="Yo you can use a placeholder" />

这将创建3个不同的小部件,并且每个小部件都有不同的配置。无需额外的JS,只需要标准化、干净和精简的代码。

2. 标准化的DOM API

DOM API也是如此。以下仅是两个示例:组合两个日期字段将范围字段与日期字段组合

3. 现代浏览器中无需JS即可运行

在旧浏览器中可以优雅地降级,并在现代浏览器中表现良好。

4. 现代浏览器中文件大小更小

特别适用于移动设备(例如iOS 5、黑莓支持日期等)。

5. 更好的用户体验(主要是移动设备)

更好的移动用户体验(更好的触摸输入UI、更好的性能、适应系统),如果您使用它:type="email"type="number"type="date"/type="range"

但是,定制化怎么办?

我在一家大型机构中担任开发人员,您完全正确,大多数客户和设计师都不会容忍太多差异,但我仍然想使用现代技术,这意味着Webshims库可以为您提供最好的两个世界。

自定义约束验证

填充部分

//polyfill constraint validation
$.webshims.polyfill('forms');

自定义错误气泡的用户界面:

//on DOM-ready
$(function(){
    $('form').bind('firstinvalid', function(e){ 
        //show the invalid alert for first invalid element 
        $.webshims.validityAlert.showFor( e.target ); 
        //prevent browser from showing native validation message 
        return false; 
    });
});

生成以下标记:

<!-- the JS code above will generate the following custom styleable HTML markup for the validation alert -->
<span class="validity-alert-wrapper" role="alert"> 
    <span class="validity-alert"> 
        <span class="va-arrow"><span class="va-arrow-box"></span></span> 
        <span class="va-box">Error message of the current field</span> 
    </span> 
</span>

自定义无效/有效表单字段的样式:

.form-ui-invalid {
    border-color: red;
}

.form-ui-valid {
    border-color: green;
}

自定义有效性提示信息的文本:

<input required data-errormessage="Hey this is required!!!" />

现在的焦点是什么:

  1. 即使没有JS也可以使用
  2. 现代浏览器只加载自定义代码(3kb min/gzipped),旧版浏览器会加载额外的API(约13kb min/gzip)(表单包含的不仅仅是约束验证API,还有自动对焦、占位符、输出等等)

那么你的特殊示例,自定义日期字段呢?

没问题:

//configure webshims to use customizable widget UI in all browsers
$.webshims.setOptions('forms-ext', { 
    replaceUI: true
});

$.webshims.polyfill('forms forms-ext');

还有这里:

  1. 在现代浏览器中仍然可以在没有JS的情况下工作。
  2. 现代浏览器仅加载UI和UI-API粘合剂,但不加载DOM-API(valueAsNumber,valueAsDate…)。

现在,这里是最好的部分:

//configure webshims to use customizable widget UI in all non mobile browsers, but a customizable one in all desktop and all non-capable mobile browsers
$.webshims.setOptions('forms-ext', { 
    //oh, I know this is bad browser sniffing :-(
    replaceUI: !(/mobile|ipad|iphone|fennec|android/i.test(navigator.userAgent))
});

$.webshims.polyfill('forms forms-ext');
  1. 减小文件大小并为移动浏览器提供更好的用户体验(大多数客户和设计师都会因为在移动端有不同的UI而喜欢你!)
  2. 在现代浏览器中即使没有JS仍然可以使用
  3. 现代浏览器只加载UI和UI-API的接口,但不加载DOM-API(如valueAsNumber、valueAsDate等)

谢谢,Alexander。实际上,我上周花时间研究了webshim——我甚至在本地运行了一个示例——非常棒,谢谢!我将尝试使用详尽的表单示例并学习更多。 - drogon
2
还有一件事。在asp.net MVC中,我们可以在服务器端代码中定义数据注释到类中。这些注释定义并提供了服务器端和客户端的验证(通过jquery表单验证插件和“不显眼的验证”)。大多数MVC开发人员都喜欢使用它,因为它使他们在进行验证时更加轻松。我还将研究最简单的方法来通过自定义不显眼的脚本来结合这两个功能... - drogon
亚历山大,你能告诉我如何让“电子邮件类型弹出框”在几秒后不消失吗?这似乎是默认行为,我怎么才能改变它的可见性,直到我点击输入框为止。看起来这是在 JavaScript 文件中发生的。那么该如何正确地更改它。 - krishna
谢谢你提供的库,我已经开始使用它了。它能被精简以减小体积吗?比如说,我只需要<input type=number>的polyfill。我该如何找出哪些文件没有被使用,以便删除它们?目前我只能通过试错来实现,但是有更好的方法吗? - engineerX
那么与SPA框架的兼容性如何呢?当我将replaceUI属性设置为true时,使用webshim会破坏所有数据绑定。有没有人有处理这个问题的经验?@alexanderfarkas - Vitalii Romaniv
显示剩余4条评论

5
支持Alexander的webshims答案,我进行了大量研究,从UX、UI和前端的角度分析了HTML5输入在跨浏览器行为上的表现。我的结论是,要想在不同设备和浏览器上实现优先的行为,唯一的方法就是使用像webshims这样的polyfill。其中很多问题都与无法利用类似于日期滚轮和数字键盘这样的设备本地功能有关,因为这些功能在桌面浏览器上没有实现。
以下是对比分析日期输入在不同本地实现和流行插件上的表现:
Date input analysis - Google spreadsheet
(您可以看到webshims得到了所有实现中最好的结果)
以下是真实世界输入类型在常见浏览器中的本地行为以及使用webshim回退的分析:
UX analysis of HTML5 inputs with webshim fallback - Google spreadsheet 以下是用于分析这些输入的演示页面:
HTML5 inputs page demo - CodePen

4

我也曾怀疑,是否真的值得通过polyfill层来代替直接使用jQuery UI。但是,在使用webshims库和HTML5之后,我立即看到了javascript代码减少了很多。不再需要验证插件。感谢Alexander创建和支持这个美妙的polyfill,webshims库。以下是在表单提交点击时进行ajax调用的示例。

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.1/jquery-ui.js" type="text/javascript"></script>
<script>
    // set options for html5shiv
    if(!window.html5){
        window.html5 = {}; 
    }
    window.html5.shivMethods = false;
</script>
<script src="webshims/js-webshim/minified/extras/modernizr-custom.js"></script>
<script src="webshims/js-webshim/minified/polyfiller.js"></script>
    <script class="example">
        $.webshims.setOptions({
            //we do not use any DOM-/JS-APIs on DOM-ready, so we do not need to delay the ready event <- good against fouc
            waitReady: false
        });
        //load all polyfill features
        $.webshims.polyfill('forms forms-ext');     
    </script>
<script type="text/javascript">
$(function(){
    var frm = $('#tstForm');
    frm.submit(function () {
    var someDate=$('#someDate').val();
     alert('someDate:'+someDate);
     // you can make your ajax call here. 

        return false;
    });
});
</script>
</head>
<body>
<form id="tstForm">
  Some Date:<input id="someDate" name="someDate" type="date" min="2013-01-01" max="2013-06-01" ></input>
  Full Name:<input id="fullName" name="fullName" type="text" required></input>
  Age:<input id="age" name="age" type="number" required min="18" max="120"></input>
  <input type="submit" value="Submit"/>
</form>

</body>
</html>

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