遅延HTML5:最初のイベントまでは無効な疑似クラス

私は最近、:invalid 疑似クラスが、ページが読み込まれるとすぐに required フォーム要素に適用されることを発見しました。たとえば、次のコードがあるとします。

…
<input name="foo" required />

次に、空のピンクの入力要素がページに表示されます。 HTML5に検証機能が組み込まれているのは素晴らしいですが、ほとんどのユーザーはフォームを検証してから、値を入力する機会はありません。最初のイベントがその要素(form submit、blur、change、それが何であれ)に影響するまで、擬似クラスのアプリケーションを遅らせる方法はありますか? JavaScriptなしでこれを行うことは可能ですか?

48
私はコメントできないので、この補足を@ user3284463に追加します。 makeDirty は、ダーティークラスを切り替えるべきではなく、将来(青色、無効な、有効な)イベントに保持する必要があります。function makeDirty ){if(!e.target.classList.contains( 'dirty'))e.target.classList.add( 'dirty'); }
追加された 著者 Abir Stolov,

9 答え

http://www.alistapart.com/articles/forward-thinking-form-validation/

フィールドは一度無効になったことを示すだけなので   フォーカス擬似クラスを使用して無効なスタイリングをトリガーします。   (当然ながら、必要なすべてのフィールドを最初から無効とフラグを立てる   設計上の選択肢が貧弱です)。

このロジックに従って、あなたのコードは次のようになります...

32
追加された
#myform:submitted input:required:invalid のように、 "submit"のようなフォームのための(現在は存在しない)pseduoクラスを想像することができます。 >。なぜなら、現時点でのシナリオは実際には直感的ではありませんが、CSSが特定の状況下でフィールドが無効であることを知ることを必ずしも期待するのは現実的ではありません(なぜなら、入力スタイルを入力フォームではなくフォームの状態に結びつけることが本当に必要です(たとえば、必須フィールドが空で親フォームが送信された場合など)。
追加された 著者 Anthony,
この回答: stackoverflow.com/questions/41619497/… 実際にこの井戸を扱う、私はそれがJavaScriptのビットを必要とする場合でも、私は思う。スタイルルールが form.submitされた入力:必須:無効になるように、フォームに「サブミット」されたクラスを追加するだけです(私が提案したのと同じです)
追加された 著者 Anthony,
また、この点を完全に排除するには、他の:valid または:invalid 入力タイプで同じ問題が発生するはずです。入力が integer 型で何も入力されていない場合、空白は有効な数値ではないため、無効として表示されるはずです。これが問題ではない唯一の理由は、 required プロパティの外側で空の値が有効な値とみなされるためです。
追加された 著者 Anthony,
「どんな手段でも理想的ではない」確かに。有効な要素にスタイリングを適用する方法はありますか?要素のフォーカスが失われた後に必要な必要なコンテンツはありませんか?私はこれをやる方法を工夫していない。
追加された 著者 Donald Jenkins,

これは純粋なCSSでは不可能ですが、JavaScriptで行うことができます。これは jQueryの例です:

<div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="true"> <div class="snippet-code">

// use $.fn.one here to fire the event only once.
$(':required').one('blur keydown', function() {
  console.log('touched', this);
  $(this).addClass('touched');
});
/**
 * All required inputs initially are yellow.
 */
:required {
  background-color: lightyellow;
}

/**
 * If a required input has been touched and is valid, it should be white.
 */
.touched:required:valid {
  background-color: white;
}

/**
 * If a required input has been touched and is invalid, it should be pink.
 */
.touched:required:invalid {
  background-color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>






</div> </div>
20
追加された
これは私が好む解決策ですが、もうjQueryは必要ありません。これは簡単なJavascriptで行うことができます。
追加された 著者 micah,
それは簡単な解決策です;)
追加された 著者 fegemo,

これらの回答は古くなっています。これで、プレースホルダpseudo-classをCSSで確認することができます。

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

input:not(:placeholder-shown):invalid {
    background-color: salmon;
}
form:invalid button {
    background-color: salmon;
    pointer-events: none;
}
<form>
    <input type="email" placeholder="[email protected]" required>
    <button type="submit">Submit</button>
</form>
</div> </div>

それはあなたにあなたの不完全な電子メールアドレスを入力すると、通常の背景から始まり、ピンク色に変わります。

14
追加された
残念ながら、唯一の妥当性検査が必須である場合は機能しません。必須フィールドに触れたとき、または必須フィールドを含むフォームを送信しようとしたときにエラーが表示されるはずです。空の必須フィールドにはプレースホルダが表示されます。
追加された 著者 Björn Tantau,
フォームに基づいて送信ボタンのトグルの例を追加しました。
追加された 著者 Carl,
IEやEdgeのサポートを気にするなら、:placeholder-shown 疑似クラスはまったくサポートされていないことに注意してください。 caniuse.com/#feat=css-placeholder-shown
追加された 著者 Leo Napoleon,

submit イベントが発生してからcheckValidityを通過しない要素ごとに発生するhtml5 invalid イベントがあります。このイベントを使用して、たとえば周囲のフォームにクラスを適用して表示することができます。このイベントが発生した後にのみ無効なスタイルが表示されます。

 $("form input, form select, form textarea").on("invalid", function() {
     $(this).closest('form').addClass('invalid');
 });

あなたのCSSは次のようになります:

:invalid { box-shadow: none; }
.invalid input:invalid,
.invalid textarea:invalid,
.invalid select:invalid { border: 1px solid #A90909 !important; background-color: #EEC2C2; }

最初の行はデフォルトのスタイリングを削除するので、フォーム要素はページのロード時にニュートラルに見​​えます。無効なイベントが発生すると(ユーザーがフォームを送信しようとすると)、要素は視覚的に無効にされます。

2
追加された

HTML5フォームの検証を使用している間は、ホイールを再発明するのではなく、ブラウザを使用して無効な投稿/フィールドを検出してみてください。

フォームに「無効」というクラスを追加するには、無効なイベントを待ち受けます。無効なクラスを追加すると、CSS3の:pseudo セレクタを使用してフォームにスタイルを設定して町に行くことができます。

例えば:

// where myformid is the ID of your form
var myForm = document.forms.myformid;

var checkCustomValidity = function(field, msg) {
    if('setCustomValidity' in field) {
        field.setCustomValidity(msg);
    } else {
        field.validationMessage = msg;
    }
};

var validateForm = function() {

   //here, we're testing the field with an ID of 'name'
    checkCustomValidity(myForm.name, '');

    if(myForm.name.value.length < 4) {
        checkCustomValidity(
           //alerts fields error message response
            myForm.name, 'Please enter a valid Full Name, here.'
        );
    }
};

/* here, we are handling your question above, by adding an invalid
   class to the form if it returns invalid.  Below, you'll notice
   our attached listener for a form state of invalid */
var styleInvalidForm = function() {
    myForm.className = myForm.className += ' invalid';
}

myForm.addEventListener('input', validateForm, false);
myForm.addEventListener('keyup', validateForm, false);
myForm.addEventListener('invalid', styleInvalidForm, true);

さて、私たちが添付した '無効な'クラスに基づいて、あなたのフォームをスタイル付けしてください。

例えば:

form.invalid input:invalid,
form.invalid textarea:invalid {
    background: rgba(255, 0, 0, .05);
    border-color: #ff6d6d;
    -webkit-box-shadow: 0 0 6px rgba(255, 0, 0, .35);
    box-shadow: 0 0 6px rgba(255, 0, 0, .35);
}
2
追加された
ええ、これはホイールよりもはるかに疑問を改造するものではありませんか?
追加された 著者 Ry-,

Mozillaはこれを独自ので処理します: moz-ui-invalid pseudoclassを使用してフォームに適用されます。 MDNは、サポートの欠如のためにこれを使用することはお勧めしません。ただし、Firefox用に変更することはできます。

:ユーザーが無効な仕様のレベル4の仕様があります同様の挙動を示す地平線。

申し訳ありませんが、これは役立たないが、私はそれがいくつかのコンテキストを提供することを願っています。

1
追加された

特定のクラスが必要な要素だけがピンクになるようにすることができます。要素を終了するときに、そのクラスを追加する各必須要素にイベントハンドラを追加します。

何かのようなもの:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var required = document.querySelectorAll('input:required');
    for (var i = 0; i < required.length; ++i) {
      (function(elem) {
        function removeClass(name) {
          if (elem.classList) elem.classList.remove(name);
          else
            elem.className = elem.className.replace(
              RegExp('(^|\\s)\\s*' + name + '(?:\\s+|$)'),
              function (match, leading) {return leading;}
          );
        }

        function addClass(name) {
          removeClass(name);
          if (elem.classList) elem.classList.add(name);
          else elem.className += ' ' + name;
        }

       //If you require a class, and you use JS to add it, you end up
       //not showing pink at all if JS is disabled.
       //One workaround is to have the class on all your elements anyway,
       //and remove it when you set up proper validation.
       //The main problem with that is that without JS, you see what you're
       //already seeing, and stuff looks hideous.
       //Unfortunately, you kinda have to pick one or the other.


       //Let non-blank elements stay "touched", if they are already,
       //so other stuff can make the element :invalid if need be
        if (elem.value == '') addClass('touched');

        elem.addEventListener('blur', function() {
          addClass('touched');
        });

       //Oh, and when the form submits, they need to know about everything
        if (elem.form) {
          elem.form.addEventListener('submit', function() {
            addClass('touched');
          });
        };
      })(required[i]);
    }
  });
</script>

もちろん、(a) DOMContentLoaded は比較的新しく、IE8が出てきたときには標準ではなかったので、IE8では attachEvent addEventListener ではなく、:required を気にするつもりはありません.HTMLを技術的にサポートしていないので5。

1
追加された

I created a small shim to deal with this in my codebase. I just start off with my <form/> element having the novalidate property along with a data-validate-on="blur" attribute. This watches for the first event of that type. This way you can still use the native :invalid CSS selectors for the form styling.

$(function() {
    $('[data-validate-on]').each(function() {
        var $form = $(this);
        var event_name = $form.data('validate-on');

        $form.one(event_name, ':input', function (event) {
            $form.removeAttr('novalidate');
        });
    });
});
1
追加された

良い方法は、:invalid、:valid をCSSクラスで抽象化し、入力フィールドがフォーカスされているかどうかを確認するJavaScriptを抽象化することです。

CSS:

input.dirty:invalid{ color: red; }
input.dirty:valid{ color: green; }

JS:

// Function to add class to target element
function makeDirty(e){
  e.target.classList.toggle('dirty');
}

// get form inputs
var inputs = document.forms[0].elements;

// bind events to all inputs
for(let input of inputs){
  input.addEventListener('invalid', makeDirty);
  input.addEventListener('blur', makeDirty);
  input.addEventListener('valid', makeDirty);
}

DEMO

0
追加された