web-dev-qa-db-ja.com

HTML5の非表示フォームコントロールの処理は意味がありますか?

JavaScriptを使用せずにフォームでクライアント側の検証をより適切に定義する機能にHTML5が追加されました。 「maxlength」や「minlength」などの属性を持つ概念はすでに存在しています。 「必須」や「パターン」などの属性で拡張されています。ただし、HTML5でもこれらの属性に制限が定義されており、WebKitブラウザーはこれらの制限を実装しています(FirefoxとOperaでそれほど遅れていない可能性があります)。

問題の制限事項 は、CSS/JavaScriptによって_display: none_または_visibility: hidden_ CSSルールを使用して非表示にされた場合のフォームコントロールの可視性に関係しています。制限は次のように定義されます。

4.10.7.1.1隠し状態

input要素のtype属性が非表示の状態[...]の場合input要素は、ユーザーによる検査または操作を意図していない値を表します。

[また、]

  • value IDL属性はこの要素に適用され、モードはデフォルトです。
  • 次のコンテンツ属性は指定してはならず、要素には適用できません:acceptaltautocompletecheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightlistmaxmaxlengthminmultiplepatternplaceholderreadonlyrequiredsizesrcstepwidth
  • 次のIDL属性とメソッドは要素に適用されません:checkedfileslistselectedOptionselectionStartselectionEndselectionDirectionvalueAsDate、およびvalueAsNumber IDL属性。 select()setSelectionRange()stepDown()、およびstepUp()メソッド。
  • inputおよびchangeイベントは適用されません。

一見すると、ユーザーが制御できないフォームコントロールに対して検証を実行する必要がないと言うのは理にかなっています。また、デフォルトのフォームコントロール要素を使用して構築されたフォームの場合、これらは理にかなっています。しかし今、リモートフォームコントロールの構築に問題が発生しています。

HTML5もCSS3も(主要なブラウザーも)、フォームコントロールのスタイル設定をはるかに簡単にしていません。 _<select>_要素はスタイルの点で依然として大幅に制限されており、_<input>_と_<button>_の両方の要素には厄介な異なるスタイル規則があります(IE以外のブラウザーでは、CSSブラウザーのターゲット設定はほぼ不可能です)。そのため、デザイナーが「きれいな」フォームコントロールを必要とする場合、HTML、CSS、JavaScriptを使用して再構築する必要がある場合があります。シミュレートされたコントロールは、CSSによって非表示にされている実際のコントロールをリモートで制御します。これは、_<select>_、_<input type="checkbox">_、および_<input type="radio">_の各要素に当てはまり、required属性を指定すると、これらすべてがWebKitブラウザーで問題を引き起こします。

HTML5仕様では、requiredなどの特定の属性は非表示のフォームコントロールに存在できないと規定されているため、ブラウザーは無効な属性に応答する必要があります。 WebKitブラウザーは、フォームをまったく送信しない(そしてJavaScriptのsubmitイベントをトリガーしない)ことで応答しています。 _<select>_要素を使用して、現在エラーが発生しています。

Chromeはコンソールへのこのエラーで失敗します:

Name = 'element-name'の無効なフォームコントロールはフォーカスできません。

Safariが失敗し、ウィンドウの下部に次のメッセージが表示される灰色のバーが表示されます。

リストからアイテムを選択してください


したがって、私の懸念は、HTML5の制限が厳しすぎるのか、この問題に誤って対処しているのかです。どちらか:

  1. HTML5の仕様には欠陥があり、別の解決策なしに追加の制限が追加されます。HTML5は、フォームコントロールが表示されない場合、ユーザーが操作できないことを前提としていますそれと。これにより、開発者は、元のフォームコントロールを非表示にしたまま、リモートで制御する要素にHTML5の検証属性を利用できなくなります。 CSSのみを使用してカスタムコントロールを作成する機能はまだありません。そのため、自分で構築する必要があります。
  2. リモートフォームコントロールを誤って処理しています。「古い」手法を使用して再定義された可能性のある問題を解決しているため、私のアプローチは時代遅れです。また、現時点でこの制限を処理しているのはWebKitだけなので、WebKitにはこれを回避するための回避策がまだありません。

現時点で考えられる唯一の回避策は

  • JavaScriptでフォームコントロールを動的に非表示にするときは常に制限された属性を削除します。つまり、HTML5の検証を犠牲にします。
  • 問題のフォームコントロールを一時的に表示してすぐに非表示にします。ただし、submitイベントが発生することはなく、clickイベントを発生させずにフォームを送信することもできるため、いつ実行されるかわかりません。送信ボタン、または
  • novalidate属性を使用しますが、HTML5検証はまだ失われます。

だから私はこれを正しく見ていますか、それとも何か不足していますか?

28
KOVIKO

まず、2つのことを混同します。 HTML5仕様が隠し状態を示している場合、その仕様はtype属性が値 "hidden"に設定されたinput要素のみを意味します。この場合、入力は検証されません。つまり、入力を無効にすることはできません。また、ブラウザはフォームの送信を中止しません。

あなたの問題は別の問題です。本当に無効な要素があり、それは視覚的にのみ非表示になり(display:noneを使用)、別の要素(または他の要素のセット)に置き換えられます。あなたの場合、問題は次のとおりです:インタラクティブなフォーム検証の場合の仕様により、ブラウザは最初の無効な要素にフォーカスし、少なくともこの要素に対して検証メッセージを表示する必要があります。

問題は、ブラウザーが非表示の要素にフォーカスしたり、この要素の下に検証メッセージを表示したりできないことです。つまり、ブラウザはフォームの送信を停止しますが、検証の問題を示す奇妙なUIを持っています。

さてあなたの質問に:これは理にかなっていますか?はい、そうです!フォーム要素のUIを変更する場合は、検証メッセージのUIも実装する必要があります。 (何かをカスタマイズしたい場合は、使用したいものすべてをカスタマイズできます)。 HTML5は、まさにこれを実現するためのAPIを提供します。

Select要素のinvalidイベントをバインドし、デフォルトのアクション(フォームの最初の無効なイベントの場合)を防止して、スタイル付きのselect要素に独自の検証ツールチップを配置する必要があります。

私のHTML5フォームポリフィル(webshimsライブラリ)では、既にコードを使用して(APIを使用して)ネイティブ要素を別の要素にリンクし、単純に検証ツールチップを生成しています。

単純なjsfiddleを作成しました。これは、select-replacementを模倣し、カスタムフォームコントロールでHTML5フォームの検証を行う方法を示しています。 ここの例 以下を見つけることができます:

HTML

<form class="example">
    <div>
        <select name="test" required>
            <option value="">empty </option>
            <option>sdadsa</option>
        </select>
    </div>

    <div>
        <input type="submit" />
    </div>
</form>

<p><a href="http://afarkas.github.com/webshim/demos/index.html" target="_blank">uses the webhsims library</a>

JavaScript

(function() {
    "use strict";
    webshims.polyfill('forms dom-support');

    $(function() {
        $('select').each(function(){
            var visualReplacement = $('<span tabinde="0">replaced select</select>');
            $(this).after(visualReplacement).hide();
            // Bind the visual element to the API element
            webshims.addShadowDom(this, visualReplacement);
        });
        $('form').on('firstinvalid', function(e){
            webshims.validityAlert.showFor(e.target);
            // Remove native validation
            return false;
        });
    });
})();
21