Gecikme HTML5: ilk etkinliğe kadar geçersiz sözde sınıf

Yakın zamanda, sayfa yüklendiğinde : geçersiz sözde sınıfının gerekli form öğeleri için geçerli olduğunu keşfettim. Örneğin, bu koda sahipseniz:


…
<input name="foo" required />

Sonra sayfanızda boş bir pembe giriş elemanı ile yüklenir. HTML5'te yerleşik doğrulamanın olması harika bir şeydir, ancak çoğu kullanıcının formda herhangi bir değer girme şansı olmadan doğrulama yapmasını beklemiyorum. Sözde sınıfın uygulanmasını o unsuru etkileyen ilk olaya kadar geciktirmenin herhangi bir yolu var mı (form gönderme, bulanıklık, değişim, uygun olan her şey)? JavaScript olmadan bunu yapmak mümkün mü?

48
Yorum yapamam, bu yüzden eki @ user3284463'e ekleyeceğim makeDirty kirli sınıfı değiştirmemeli, gelecekteki (mavi, geçersiz, geçerli) olaylarda kalmasını sağlamalıdır makeDirty (e ) {if (! e.target.classList.contains ('kirli')) e.target.classList.add ('kirli'); }
katma yazar Abir Stolov, kaynak

9 cevap

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

Sadece bir alanın sahip olduğu zaman bir alanın geçersiz olduğunu belirtmek istediğimizden   Odaklama, geçersiz stil tetiklemek için odak sözde sınıfı kullanıyoruz.   (Doğal olarak, gerekli tüm alanları başlangıçtan itibaren geçersiz olarak işaretleme   kötü tasarım tercihi olurdu.)

Bu mantığı takiben, kodun böyle bir şey görecekti ...


<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>

Ve tabii ki, IE8'de olduğu gibi (a) DOMContentLoaded nispeten yeni ve IE8 çıktığında standart değildi, (b) IE8 attachEvent kullanıyor HTML'yi teknik olarak desteklemediği için DOM standardı addEventListener yerine ve (c) IE8, : required ile ilgilenmeyecektir. 5.

1
katma

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
katma

Bir CSS sınıfı ile : geçersiz, geçerli soyut ve sonra giriş alanının odaklanıp odaklanmadığını kontrol etmek için JavaScript'in iyi bir yolu.

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
katma