Quello che ti manca è una comprensione del markup semantico e del DOM.
Realisticamente, puoi praticamente fare quello che vuoi con il markup HTML5 e la maggior parte dei browser lo analizzerà. L'ultima volta che ho controllato, WebKit / Blink consente persino pseudo-elementi all'interno di <input>
elementi , il che è una chiara violazione delle specifiche: Gecko non così tanto. Tuttavia, fare quello che vuoi con il tuo markup lo invaliderà senza dubbio per quanto riguarda la semantica.
Perché inseriamo <input>
elementi all'interno di <form>
elementi? Per lo stesso motivo per cui inseriamo i <li>
tag all'interno degli elementi <ul>
e <ol>
: è il luogo a cui appartengono. È semanticamente corretto e aiuta a definire il markup. Parser, screen reader e vari software possono comprendere meglio il markup quando è semanticamente corretto, quando il markup ha un significato, non solo una struttura.
L' <form>
elemento consente anche di definire method
e action
attributi, che dicono al browser cosa fare quando il modulo viene inviato. AJAX non è uno strumento di copertura al 100% e, come sviluppatore web, dovresti esercitarti in un degrado grazioso: i moduli dovrebbero essere in grado di essere inviati e i dati trasferiti, anche quando JS è disattivato.
Infine, i moduli sono tutti registrati correttamente nel DOM. Possiamo dare un'occhiata a questo con JavaScript. Se apri la tua console proprio in questa pagina e digita:
document.forms
Avrai una bella raccolta di tutti i moduli sulla pagina. La barra di ricerca, le caselle dei commenti, la casella delle risposte: tutte le forme corrette. Questa interfaccia può essere utile per accedere alle informazioni e interagire con questi elementi. Ad esempio, i moduli possono essere serializzati molto facilmente.
Ecco del materiale da leggere:
Nota: gli <input>
elementi possono essere utilizzati al di fuori dei moduli, ma se la tua intenzione è di inviare i dati in qualsiasi modo, dovresti utilizzare un modulo.
Questa è la parte della risposta in cui capovolgo la domanda.
In che modo sto rendendo la mia vita più difficile evitando le forme?
Prima di tutto - elementi contenitore. Chi ne ha bisogno, vero ?!
Certamente il tuo piccolo <input>
e gli <button>
elementi sono annidati all'interno di una sorta di elemento contenitore? Non possono semplicemente fluttuare nel mezzo di tutto il resto. Quindi se non una <form>
, allora cosa? A <div>
? A <span>
?
Questi elementi devono risiedere da qualche parte e, a meno che il tuo markup non sia un pasticcio folle, l'elemento contenitore può essere solo un modulo.
No? Oh.
A questo punto le voci nella mia testa sono molto curiose di come crei i tuoi gestori di eventi per tutte queste diverse situazioni AJAX. Devono essercene molte, se è necessario ridurre il markup per salvare byte. Quindi devi creare funzioni personalizzate per ogni evento AJAX che corrisponde a ogni "set" di elementi - che devi avere come target individualmente o con classi, giusto? Non c'è modo di raggruppare davvero questi elementi in modo generico, poiché abbiamo stabilito che si limitano a vagare per il markup, facendo qualsiasi cosa fino a quando non sono necessari.
Quindi personalizzi il codice di alcuni gestori.
$('#searchButton').on('click', function (e) {
e.preventDefault();
var search = $('#mySearch');
$.ajax({
url: 'http://example.com/text',
type: 'GET',
dataType: 'text',
data: 'query=' + search.val(),
success: function (data) {
console.log(data);
}
});
});
$('#login').on('click', function (e) {
e.preventDefault();
var user = $('#username'),
pass = $('#password'),
rem = $('#remember');
$.ajax({
url: 'http://example.com/login',
type: 'POST',
data: user.add(pass, rem).serialize(),
dataType: 'text',
success: function (data) {
console.log(data);
}
});
});
<!-- No containers, extra markup is silly. -->
<input type="text" id="mySearch" value="query" />
<button id="searchButton">Search</button>
<input type="text" id="username" name="username" value="user" />
<input type="password" id="password" name="password" value="pass" />
<input type="checkbox" id="remember" name="remember" checked /> stay logged in
<button id="login">Login</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Questa è la parte in cui dici qualcosa come:
'Uso totalmente le funzioni riutilizzabili però. Smettila di esagerare.
Abbastanza giusto, ma è comunque necessario creare questi set di elementi unici o set di classi target, giusto? Devi ancora raggruppare questi elementi in qualche modo.
Prestami i tuoi occhi (o le tue orecchie, se stai usando uno screen reader e hai bisogno di assistenza - per fortuna potremmo aggiungere un po 'di ARIA a tutto questo markup semantico , giusto?), E osserva il potere della forma generica.
function genericAjaxForm (e) {
e.preventDefault();
var form = $(this);
return $.ajax({
url: form.attr('action'),
type: form.attr('method'),
dataType: form.data('type'),
data: form.serialize()
});
}
$('#login-form').on('submit', function (e) {
genericAjaxForm.call(this, e).done(function (data) {
console.log(data);
});
});
<form action="http://example.com/login" method="POST" data-type="text" id="login-form">
<input type="text" name="username" value="user" />
<input type="password" name="password" value="mypass" />
<label>
<input type="checkbox" name="remember" /> Remember me
</label>
<button type="submit">Login</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Possiamo usarlo con qualsiasi forma comune, mantenere la nostra graziosa degradazione e lasciare che la forma descriva completamente come dovrebbe funzionare. Possiamo espandere questa funzionalità di base mantenendo uno stile generico : più modulare, meno mal di testa. JavaScript si preoccupa solo delle sue cose, come nascondere gli elementi appropriati o gestire le risposte che otteniamo.
E ora dici:
"Ma racchiudo le mie pseudo-forme in <div>
elementi che hanno ID specifici: posso quindi indirizzare gli input liberamente con con .find
, e .serialize
loro, e ..."
Oh, cos'è quello? Hai davvero avvolto i tuoi <input>
elementi in un contenitore?
Allora perché non è ancora un modulo?