HTML5 类型检测和插件初始化
A 部分:
我知道有很多东西可以告诉您浏览器是否支持特定的 HTML5 属性,例如 http://diveintohtml5.info/detect.html,但它们不会告诉您如何从各个元素获取类型并使用该信息初始化你的插件。
所以我尝试了:
alert($("input:date"));
//returns "[object Object]"
alert($("input[type='date']"));
//returns "[object Object]"
alert($("input").attr("type"));
//returns "text" ... which is a lie. it should have been "date"
这些都不起作用。
我最终想出了这个(确实有效):
var inputAttr = $('<div>').append($(this).clone()).remove().html().toLowerCase();
alert(inputAttr);
// returns "<input min="-365" max="365" type="date">"
谢谢:http://jquery-howto.blogspot.com/2009/02/how-to-get-full-html-string-include.html
所以我的第一个问题是: 1. 为什么在不支持html5的浏览器中无法读取“type”属性?您可以编造任何其他属性和虚假值并读取它。 2. 为什么我的解决方案有效?为什么它是否在 DOM 中很重要?
B 部分:
下面是我使用检测器的基本示例:
<script type="text/javascript" >
$(function () {
var tM = document.createElement("input");
tM.setAttribute("type", "date");
if (tM.type == "text") {
alert("No date type support on a browser level. Start adding date, week, month, and time fallbacks");
// Thanks: http://diveintohtml5.ep.io/detect.html
$("input").each(function () {
// If we read the type attribute directly from the DOM (some browsers) will return unknown attributes as text (like the first detection). Making a clone allows me to read the input as a clone in a variable. I don't know why.
var inputAttr = $('<div>').append($(this).clone()).remove().html().toLowerCase();
alert(inputAttr);
if ( inputAttr.indexOf( "month" ) !== -1 )
{
//get HTML5 attributes from element
var tMmindate = $(this).attr('min');
var tMmaxdate = $(this).attr('max');
//add datepicker with attributes support and no animation (so we can use -ms-filter gradients for ie)
$(this).datepick({
renderer: $.datepick.weekOfYearRenderer,
onShow: $.datepick.monthOnly,
minDate: tMmindate,
maxDate: tMmaxdate,
dateFormat: 'yyyy-mm',
showAnim: ''});
}
else
{
$(this).css('border', '5px solid red');
// test for more input types and apply init to them
}
});
}
});
</script>
实例:http://joelcrawfordsmith.com/sandbox/html5-type-detection.html
还有一个恩惠/问题: 谁能帮我减少 HTML5 输入类型修复程序中的一些内容?
我已经关闭了该功能(添加了 IE6-IE8 和 FF 的后备,而不添加要初始化的类)
是否有更有效的方法来迭代神秘输入类型的 DOM? 在我的示例中,我应该使用 If Else、函数还是案例?
谢谢大家,
乔尔
PART A:
I know there are a lot of things out there that tell you if a browser supports a certain HTML5 attribute, for example http://diveintohtml5.info/detect.html, but they don't tell you how to acquire the type from individual elements and use that info to init your plugins.
So I tried:
alert($("input:date"));
//returns "[object Object]"
alert($("input[type='date']"));
//returns "[object Object]"
alert($("input").attr("type"));
//returns "text" ... which is a lie. it should have been "date"
None those worked.
I eventually came up with this (that does work):
var inputAttr = $('<div>').append($(this).clone()).remove().html().toLowerCase();
alert(inputAttr);
// returns "<input min="-365" max="365" type="date">"
Thanks: http://jquery-howto.blogspot.com/2009/02/how-to-get-full-html-string-including.html
So my first question:
1. Why can I not read the "type" attribute in browsers that don't support html5? You can make up any other attribute and bogus value and read it.
2. Why does my solution work? Why does it matter if its in the DOM or not?
PART B:
Below is a basic example of what I am using the detector for:
<script type="text/javascript" >
$(function () {
var tM = document.createElement("input");
tM.setAttribute("type", "date");
if (tM.type == "text") {
alert("No date type support on a browser level. Start adding date, week, month, and time fallbacks");
// Thanks: http://diveintohtml5.ep.io/detect.html
$("input").each(function () {
// If we read the type attribute directly from the DOM (some browsers) will return unknown attributes as text (like the first detection). Making a clone allows me to read the input as a clone in a variable. I don't know why.
var inputAttr = $('<div>').append($(this).clone()).remove().html().toLowerCase();
alert(inputAttr);
if ( inputAttr.indexOf( "month" ) !== -1 )
{
//get HTML5 attributes from element
var tMmindate = $(this).attr('min');
var tMmaxdate = $(this).attr('max');
//add datepicker with attributes support and no animation (so we can use -ms-filter gradients for ie)
$(this).datepick({
renderer: $.datepick.weekOfYearRenderer,
onShow: $.datepick.monthOnly,
minDate: tMmindate,
maxDate: tMmaxdate,
dateFormat: 'yyyy-mm',
showAnim: ''});
}
else
{
$(this).css('border', '5px solid red');
// test for more input types and apply init to them
}
});
}
});
</script>
Live example: http://joelcrawfordsmith.com/sandbox/html5-type-detection.html
And a favor/question:
Can anyone help me cut some fat in my HTML5 input type fixer?
I have the functionality down (adds fallbacks to IE6-IE8, and FF with out adding classes to init off of)
Are there are more efficient methods for iterating over the DOM for mystery input types?
And should I be using an If Else, or a function, or a case in my example?
Thanks All,
Joel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
好吧,我认为这里描述的检测浏览器是否支持日期输入类型的方法太复杂了,如果您想要一种更简单的方法,您可以这样做:
一旦您将输入集中到类型上,就会执行此函数="date",如果页面上尚不存在也没关系,听众将一直观看,直到正文上有新的输入[type="date"],但正如评论中所建议的,如果您有您知道的更接近的容器将始终包含输入,那么您可以更改它而不是“主体”。
JS Listener 无论如何都很快
Ok I think that the methods described here to detect if a browser supports the date inpu type are to complicated, if you'd like an easier approach you could just do something like this:
This function will be executed once you focus an input with type="date", it doesnt matter if it doesn't exist on the page yet, the listener will be watching until there's a new input[type="date"] on body, but as suggested on the comments, if you have a closer container that you know will always contain the inputs, well you could change it instead of having "body".
JS Listeners are fast anyway
检测支持的输入类型的一种更优越的方法是简单地创建一个输入元素并循环所有可用的不同输入类型并检查
type
更改是否持续:这实际上利用了浏览器的事实不支持该特定输入类型的将回退到使用文本,从而允许您测试它们是否受支持。
例如,您可以使用
supported['week']
来检查week
输入类型的可用性,并通过此进行回退。在这里查看一个简单的演示: http://www.jsfiddle.net/yijian/r5Wsa /2/。您还可以考虑使用 Modernizr 进行更强大的 HTML5 功能检测。最后,无论您相信与否,获取
outerHTML
的更好方法是使用outerHTML
。而不是为什么不直接使用:(
是的,如您所见,有一个警告 - Firefox 不支持
outerHTML
,因此我们需要一个简单的解决方法,来自 这个堆栈溢出问题)。编辑:从以下页面找到了一种测试本机表单 UI 支持的方法:http://miketaylr.com/code/html5-forms-ui-support.html。以某种方式支持这些类型的 UI 的浏览器应该还可以防止在这些字段中输入无效值,因此我们上面所做的测试的逻辑扩展如下:
同样,不是 100 %可靠 - 这仅适用于对其值有一定限制的类型,并且绝对不是很好,但这是朝着正确方向迈出的一步,并且现在肯定会解决您的问题。
在此处查看更新的演示:http://www.jsfiddle.net/yijian/ r5Wsa/3/
A far superior method for detecting supported input types is to simply create an input element and loop through all of the different input types available and check if the
type
change sticks:This actually makes use of the fact that browsers which do not support that particular input type will fall back to using text, thereby allowing you to test if they're supported or not.
You can then use
supported['week']
, for instance, to check for the availability of theweek
input type, and do your fallbacks through this. See a simple demo of this here: http://www.jsfiddle.net/yijiang/r5Wsa/2/. You might also consider using Modernizr for more robust HTML5 feature detection.And finally, a better way to get
outerHTML
is to, believe it or not, useouterHTML
. Instead ofWhy not just use:
(Yes, as you can see, there is a caveat -
outerHTML
isn't supported by Firefox, so we're going to need a simple workaround, from this Stack Overflow question).Edit: Found a method to do testing for native form UI support, from this page: http://miketaylr.com/code/html5-forms-ui-support.html. Browsers that support the UI for these types in some way should also prevent invalid values from been entered into these fields, so the logical extension to the test we're doing above would be this:
Again, not 100% reliable - this is only good for types that have certain restrictions on their values, and definitely not very good, but it's a step in the right direction, and certainly would solve your problem now.
See the updated demo here: http://www.jsfiddle.net/yijiang/r5Wsa/3/
请求 type 属性并不适用于所有 Android 原生浏览器。他们假装支持 inputType="date",但他们不提供用于日期输入的 UI(例如日期选择器)。
此功能检测对我有用:
技巧是在日期字段中设置非法值。如果浏览器清理此输入,它还可以提供日期选择器。
Asking for the type attribute does not work in all Android stock browsers. They pretend that they support inputType="date", but they do not offer an UI (datepicker e.g.) for date inputs.
This feature detection worked for me:
The trick is to set an illegal value into a date field. If the browser sanitises this input, it could also offer a datepicker.
type 属性不是“虚构”元素,它在此处定义:
http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4
...浏览器只“知道”那里定义的@type值(除非它们支持 HTML5——它定义了一些新值,如“日期”、“电子邮件”等)
当您查询 type 属性时,某些浏览器会向您返回“文本”,因为如果浏览器不支持“日期”类型(或任何它不理解的内容),然后它会回退到默认值 - 即 type="text"
您是否想过在输入中添加一个类名(class="date"),然后您就可以$('.date').each() 然后你检测该集合
The type attribute isn't a "made-up" element, it's defined here:
http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4
...and browsers only "know" about the @type values defined there (unless they are HTML5 aware -- which has defined some new values like "date", "email" etc)
When you query the type attribute some browsers return "text" to you because if a browser doesn't support the "date" type (or anything it doesn't understand) then it falls back to the default value -- which is type="text"
Have you thought of adding a classname (class="date") to the inputs as well then you can just $('.date').each() and then do you detection on that set
我认为这是 JQuery 中的一个错误!如果您查看 JQuery 代码本身中的 attr() 函数,JQuery 首先尝试使用括号表示法获取您传入的名称的值。如果它不是未定义的,那么它返回该值。如果未定义,则使用 getAttribute() 方法。
Jquery 对 $("#elem").attr(name) 执行类似的操作:
问题是 Jquery 假设如果 elem[name] 不是未定义的,则 elem[name] 是正确的。
考虑以下示例:
当您传入 .attr("type") 时,myInput['type'] 返回“text”,因此 Jquery 返回“text”。如果您传入 .attr("joel"),则 myInput['joel'] 返回未定义,因此 Jquery 使用 getAttribute('joel') 代替返回“crawford”。
I would argue this is a bug in JQuery! If you look at the attr() function in the JQuery code itself, JQuery first trys to get a value for the name you passed in using bracket notation. If it is not undefined, then it returns that value. If it is undefined, then it usess the getAttribute() method instead.
Jquery does something similar to this for $("#elem").attr(name):
The problem is Jquery is assuming if elem[name] is not undefined, then elem[name] is correct.
Consider the following example:
When you pass in .attr("type"), myInput['type'] returns "text", so Jquery returns "text". If you passed in .attr("joel"), myInput['joel'] returns undefined, so then Jquery uses getAttribute('joel') instead which returns "crawford".
您无法在不支持此功能的浏览器中获取 type="date"。如果浏览器检测到它不理解的类型属性,则会使用 type="text" (默认)覆盖它。
解决这个问题的方法(使用 jQuery)就是简单地添加类日期。
然后你可以做类似的事情
You cannot get type="date" in a browser that doesn't support this. If a browser detects a type-attribute it doesn't understand it overrides it with the type="text" (default).
A way around this (using jQuery) is simply to add the class date as well.
Then you can do something like
只是
tester.type = i;
在 IE 中抛出异常。固定版本:永远测试,永远不要盲目复制粘贴!
Just
tester.type = i;
throws exception in IE. Fixed version:Always test, never blindly copy-paste !
下面是一个 jQuery 脚本,用于检测浏览器是否支持 HTML5
date
格式,如果支持,它将所有date
字段值更改为yyyy-mm-dd
> 格式,并将所有datetime
字段值设置为yyyy-mm-dd hh:mm:ss
格式。Here's a jQuery script that detects whether the browser supports HTML5
date
format, and if so, it changes alldate
field values toyyyy-mm-dd
format, and alldatetime
field values toyyyy-mm-dd hh:mm:ss
format.