13

パート A:

http://diveintohtml5.info/detect.htmlのように、ブラウザーが特定の HTML5 属性をサポートしているかどうかを教えてくれるものがたくさんあることは知っていますが、個々の属性から型を取得する方法は教えてくれません。要素を作成し、その情報を使用してプラグインを初期化します。

だから私は試しました:

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、関数、またはケースを使用する必要がありますか?

皆さんありがとう、

ジョエル

4

8 に答える 8

26

サポートされている入力タイプを検出するためのはるかに優れた方法は、入力要素を作成し、使用可能なすべての異なる入力タイプをループして、type変更が適用されるかどうかを確認することです。

var supported = { date: false, number: false, time: false, month: false, week: false },
    tester = document.createElement('input');

for (var i in supported){
    try {
        tester.type = i;
        if (tester.type === i){
            supported[i] = true;
        }
    } catch (e) {
        // IE raises an exception if you try to set the type to 
        // an invalid value, so we just swallow the error
    }
}

これは実際には、その特定の入力タイプをサポートしていないブラウザがテキストの使用にフォールバックするという事実を利用しているため、サポートされているかどうかをテストできます。

次にsupported['week']、たとえば、を使用してweek入力タイプが使用可能かどうかを確認し、これを介してフォールバックを実行できます。ここでこれの簡単なデモを参照してください:http ://www.jsfiddle.net/yijiang/r5Wsa/2/ 。より堅牢なHTML5機能検出のためにModernizrの使用を検討することもできます。


そして最後に、取得するためのより良い方法outerHTMLは、信じられないかもしれませんが、を使用することouterHTMLです。それ以外の

var inputAttr = $('<div>').append($(this).clone()).remove().html().toLowerCase();

使用しない理由:

var inputAttr = this.outerHTML || new XMLSerializer().serializeToString(this);

(はい、ご覧のとおり、注意点があります-Firefoxではサポートされていないため、このStack Overflowの質問outerHTMLから簡単な回避策が必要になります)。


編集:このページから、ネイティブフォームUIサポートのテストを行う方法を見つけました:http://miketaylr.com/code/html5-forms-ui-support.html。これらのタイプのUIを何らかの方法でサポートするブラウザーは、これらのフィールドに無効な値が入力されるのを防ぐ必要があるため、上記で行っているテストの論理的な拡張は次のようになります。

var supported = {date: false, number: false, time: false, month: false, week: false},
    tester = document.createElement('input');

for(var i in supported){
    tester.type = i;
    tester.value = ':(';

    if(tester.type === i && tester.value === ''){
        supported[i] = true;
    }
}

繰り返しになりますが、100%信頼できるわけではありません。これは、値に特定の制限があるタイプにのみ有効であり、間違いなくあまり良くありませんが、正しい方向への一歩であり、確かに今すぐ問題を解決します。

ここで更新されたデモを参照してください:http ://www.jsfiddle.net/yijiang/r5Wsa/3/

于 2010-11-12T02:31:56.967 に答える
10

type 属性の要求は、すべての Android ストック ブラウザーで機能するとは限りません。彼らは inputType="date" をサポートするふりをしていますが、日付入力用の UI (datepicker など) を提供していません。

この機能検出は私にとってはうまくいきました:

   (function() {
        var el = document.createElement('input'),
            notADateValue = 'not-a-date';
        el.setAttribute('type','date');
        el.setAttribute('value', notADateValue);
        return el.value !== notADateValue;
    })();

トリックは、日付フィールドに不正な値を設定することです。ブラウザがこの入力をサニタイズすると、日付ピッカーも提供される可能性があります。

于 2013-10-09T14:14:31.617 に答える
3

type属性は「作り上げられた」要素ではなく、ここで定義されています。

http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.4

...そしてブラウザはそこで定義された@type値についてのみ「知っている」(HTML5に対応していない限り-「date」、「email」などのいくつかの新しい値を定義している)

type属性をクエリすると、一部のブラウザは「テキスト」を返します。これは、ブラウザが「日付」タイプ(または理解できないもの)をサポートしていない場合、デフォルト値(type =)にフォールバックするためです。 "文章"

入力にクラス名(class = "date")を追加することも考えたことがありますか?それなら$('。date')。each()だけで、そのセットで検出できますか

于 2010-11-12T00:53:22.303 に答える
3

これは JQuery のバグだと思います。 JQuery コード自体の attr() 関数を見ると、JQuery はまず、ブラケット表記を使用して、渡された名前の値を取得しようとします。未定義でない場合は、その値を返します。未定義の場合は、代わりに getAttribute() メソッドを使用します。

Jquery は、$("#elem").attr(name) に対して次のような処理を行います。

 if (elem[ name ] !== undefined)
 {
    return elem[name];
 }
 else
 {
    return elem.getAttribute( name )
 }

問題は、elem[name] が未定義ではない場合、elem[name] が正しいと Jquery が想定していることです。

次の例を検討してください。

<input type="date" id="myInput" name="myInput" joel="crawford" />    

var myInput = document.getElementById('myInput');

alert(myInput['type']);//returns text    
alert(myInput.getAttribute('type'));//returns date
alert($("#myInput").attr('type'));//returns text

alert(myInput['joel']);//returns undefined
alert(myInput.getAttribute('joel'));//returns crawford
alert($("#myInput").attr('joel'));//returns crawford

.attr("type") を渡すと、myInput['type'] は "text" を返すため、Jquery は "text" を返します。.attr("joel") を渡した場合、myInput['joel'] は undefined を返すため、Jquery は代わりに getAttribute('joel') を使用し、"crawford" を返します。

于 2010-11-18T17:50:51.740 に答える
0

これに対応していないブラウザでは type="date" を取得できません。ブラウザが type-attribute を検出した場合、ブラウザはそれを理解できないため、type="text" (デフォルト) でオーバーライドします。

これを (jQuery を使用して) 回避する方法は、単純にクラスの日付も追加することです。

次に、次のようなことができます

$('input.date').each(function() {
    var $this = $(this);
    if($this.attr('type') != 'date') $this.datepicker();
});
于 2010-11-12T01:03:34.807 に答える
0

ブラウザが日付入力タイプをサポートしているかどうかを検出するためにここで説明されている方法は複雑すぎると思います。より簡単なアプローチが必要な場合は、次のようにすることができます。

/*
 * Instead of body, you could use the closest parent where you know your input is going to be 
 */
$("body").on("focus", "input[type='date']", function(){
    let attribute, property;
    attribute= $(this).attr("type").toUpperCase();
    property= $(this).prop("type").toUpperCase();
    if(attribute!== property){
        console.log("This browser doe not support type='date'");
        //Pop up your own calendar or use a plugin 
    }
});

この関数は、type="date" で入力にフォーカスすると実行されます。ページにまだ存在しないかどうかは関係ありません。リスナーは、body に新しい input[type="date"] があるまで監視します。 、しかし、コメントで提案されているように、常に入力が含まれていることがわかっているより近いコンテナーがある場合は、「本体」の代わりにそれを変更できます。

JSリスナーはとにかく速い

于 2021-05-07T14:26:18.660 に答える