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

32
katma
"Gönderilmiş" gibi formlar için bir (varolmayan) pseduo sınıfı hayal edebiliyorum, böylece #myform: gönderilmiş girdi: gerekli: geçersiz . Çünkü şu anki senaryo gerçek anlamda bir uyarı olmamasına rağmen, CSS'nin bir alanın belirli koşullar altında geçersiz olduğunu bilmesini beklemek gerçekçi değildir (bildiği kadarıyla, bunu neden hemen yapmasın ki?) Giriş stilini, formun kendisine değil, formun durumuna bağlamayı gerçekten istiyorsunuz (örneğin, gerekli alan boşsa VE ana form gönderildiğinde).
katma yazar Anthony, kaynak
Bu cevap: stackoverflow.com/questions/41619497/… aslında bu kuyu ile ilgilenir, bence, biraz JavaScript gerektirir. Bu sadece "önerdiğim gibi!" Formuna "gönderilmiş" bir sınıf ekler. Böylece stil kuralları form.submitted girdi olabilir: required: invalid
katma yazar Anthony, kaynak
Ayrıca, bu noktayı tamamen tüketmek için, aynı sorun diğer : geçerli veya : geçersiz giriş türleri ile mevcut olmalıdır. Bir giriş tamsayı ise ve hiçbir şey girilmezse, boş geçersiz bir sayısal değer olmadığından geçersiz olarak oluşturulmalıdır. Bunun bir sorun olmaması tek neden, gerekli özelliğinin dışında, boş bir değerin geçerli bir değer olarak kabul edilmesidir.
katma yazar Anthony, kaynak
"Hiçbir şekilde ideal değil." Aslında. Öğe, odağı kaybettikten sonra geçerli, ancak değil gerekli içeriğe stil uygulamak için bir yol var mı? Bunu yapmanın bir yolu olmadı.
katma yazar Donald Jenkins, kaynak

Bu, salt CSS'de mümkün değildir, ancak JavaScript ile yapılabilir. Bu bir jQuery örneğidir :

<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
katma
Tercih ettiğim çözüm bu, ancak artık jQuery'ye ihtiyacınız yok. Bu basit Javascript ile yapılabilir.
katma yazar micah, kaynak
Bu basit bir çözüm;)
katma yazar fegemo, kaynak

Bu cevaplar güncel değil. Şimdi bunu, CSS ile bir yer tutucu sözde sınıfını kontrol ederek yapabilirsiniz.

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

Normal bir arka planla başlar ve size tamamlanmamış e-posta adresini girerken pembeye dönüşür.

14
katma
Ne yazık ki, tek onayınız gerekli olduğunda işe yaramaz. Zorunlu bir alana dokunduğunuzda veya gerekli alanları içeren bir form göndermeye çalıştığınızda bir hata göstermelidir. Boş bir zorunlu alan, yer tutucuyu hala gösterecektir.
katma yazar Björn Tantau, kaynak
Forma dayalı olarak gönderme düğmesi geçişinin bir örneğini ekledim.
katma yazar Carl, kaynak
IE veya Edge desteğini önemsiyorsanız, : yer tutucu gösterilen sözde sınıfının hiç desteklenmediğini belirtmek gerekir. caniuse.com/#feat=css-placeholder-shown
katma yazar Leo Napoleon, kaynak

CheckValidity değerini geçmeyen her öğe için submit olayı oluşmadan önce form öğelerinde tetiklenen bir html5 invalid olayı var. Örneğin, çevreleyen forma bir sınıf uygulamak ve bu olayı görüntülemek için bu olayı kullanabilirsiniz: yalnızca bu olaydan sonra geçersiz stiller.

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

CSS’niz böyle bir şeye benzeyecekti:

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

İlk satır varsayılan stili kaldırır, böylece sayfa öğelerinde form öğeleri nötr görünür. Geçersiz etkinlik tetiklendiğinde (bir kullanıcı formu göndermeye çalıştığında), öğeler görünür şekilde geçersiz hale getirilir.

2
katma

HTML5 formu doğrulamasını kullanırken, tekerleği yeniden icat etmek yerine, geçersiz gönderimleri/alanları tespit etmek için tarayıcıyı kullanmayı deneyin.

Formunuza "geçersiz" bir sınıf eklemek için geçersiz olayını dinleyin. 'Geçersiz' sınıfı eklendiğinde, CSS3 : sözde seçicilerini kullanarak formunuzu şekillendirerek şehre gidebilirsiniz.

Örneğin:

// 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);

Şimdi, eklediğiniz 'geçersiz' sınıfa dayanarak formunuzu uygun gördüğünüz şekilde biçimlendirin.

Örneğin:

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
katma
Er, bu tekerleği bu sorudan çok daha fazla bir heck olarak yeniden icat etmiyor mu?
katma yazar Ry-, kaynak

Mozilla bunu kendi ile halleder: - moz-ui-invalid , yalnızca etkileşimde bulunduktan sonra formlar için geçerli olan pseudoclass. MDN, destek eksikliğinden dolayı bunu önermez. Ancak, Firefox için değiştirebilirsiniz.

Bir : kullanıcı-geçersiz spesifikasyonunun 4. düzey spesifikasyonu var benzer davranışlar sunacak ufuk.

Maalesef bu yardımcı olmazsa, umarım biraz bağlam sunar.

1
katma

Bunu, yalnızca ve için belirli bir sınıfa sahip olan elemanların pembe olması için yapabilirsiniz. Öğeyi terk ettiğinizde bu sınıfı ekleyen her gerekli öğeye bir olay işleyici ekleyin.

Gibi bir şey:

<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