Filtrarea și validarea datelor PHP. Greșeli frecvente. Filtre de imagine CSS Pregătirea unei interogări SQL și preluarea datelor din baza de date
Folosind pseudo-class:checked, puteți comuta stările elementelor, cum ar fi casetele de selectare sau butoanele radio. În acest tutorial, vom explora această proprietate CSS3 prin crearea unui filtru de portofoliu experimental care va comuta stările elementelor de un anumit tip.
Acest tutorial a fost inspirat de experimentul genial al lui Roman Komarov „Filtrarea elementelor fără JS”, în care folosește casete de selectare și butoane radio pentru a filtra formele colorate.
Marcaj HTML
Să începem cu marcajul. Scopul nostru este să creăm patru butoane de filtrare, după ce facem clic pe care vor apărea sau vor dispărea elementele de portofoliu corespunzătoare. Deci, vom folosi mai multe butoane radio, toate având același nume, deoarece trebuie să aparțină aceluiași grup (deci un singur buton radio va avea o stare „verificată”). În mod implicit, dorim ca toate butoanele radio să fie selectate sau bifate. Vom adăuga câteva etichete pentru butoanele radio, pe care le vom folosi pentru a ascunde butoanele radio. Făcând clic pe etichetă, se va selecta butonul radio cu id-ul corespunzător:
Toate >
Web Design >
Ilustrare >
Design icoană >
>
Lista neordonată va conține toate articolele din portofoliu, cu link-uri către imagini. Fiecare element de listă va avea o clasă, pe baza căreia elementele vor fi filtrate atunci când facem clic pe unul dintre butoanele radio.
CSS
Vom crea trei exemple ale acestui efect, dar mai întâi să ne uităm la stilurile generale.
Omit toate prefixele browserului, dar le puteți găsi în surse.
Containerul principal va avea o lățime fixă:
Ff-container(
lățime: 564px;
margine: 10px auto 30px automat;
}
Etichetele de etichetă vor ascunde butoanele radio și le vom oferi un gradient și câteva umbre subtile:
Eticheta containerului Ff(
font-family: "BebasNeueRegular" , "Arial Narrow" , Arial, sans-serif ;
latime: 25%;
înălțime: 30px;
cursor: pointer;
culoare: #777;
text-shadow : 1px 1px 1px rgba(255 , 255 , 255 , 0,8 );
înălțimea liniei: 33px;
dimensiunea fontului: 19px;
fundal: liniar-gradient(sus , #ffffff 1% , #eaeaea 100% );
plutire: stânga;
cutie-umbra:
0px 0px 0px 1px #aaa ,
1px 0px 0px 0px rgba(255 , 255 , 255 , 0.9 ) inset ,
0px 1px 2px rgba(0 , 0 , 0 , 0,2 );
}
Pentru prima și ultima etichetă de etichetă, vom crea colțuri rotunjite:
Ff-container label.ff-label-type-all(
raza-chenar: 3px 0px 0px 3px ;
}
.ff-container label.ff-label-type-3 (
raza-chenar: 0px 3px 3px 0px ;
}
Pentru fiecare buton radio bifat, vom crea stiluri care simulează efectul de „clic”:
Ff-container input.ff-selector-type-all : verificat ~ label.ff-label-type-all,
.ff-container input.ff-selector-type-1 : verificat ~ label.ff-label-type-1 ,
.ff-container input.ff-selector-type-2 : verificat ~ label.ff-label-type-2 ,
.ff-container input.ff-selector-type-3 : verificat ~ label.ff-label-type-3 (
fundal: gradient-liniar(sus , #646d93 0% , #7c87ad 100% );
culoare : #424d71 ;
text-shadow : 0px 1px 1px rgba(255 , 255 , 255 , 0,3 );
cutie-umbra:
0px 0px 0px 1px #40496e ,
0 1px 2px rgba(0 , 0 , 0 , 0.1 ) inset ;
}
Deoarece avem toate elementele noastre la același nivel, folosim combinatorul general de frați, care este notat cu simbolul tilde (~). Selector în vedere input.ff-selector-type-3:verificat ~ label.ff-label-type-3înseamnă că elementul intrare.ff-selector-tip-3:verificat urmează elementul etichetă.ff-etichetă-tip-3în ierarhia documentelor, excluzând diferite comentarii etc., și trebuie să aibă același părinte. Acest „truc” ne va permite, de asemenea, să obținem diferite tipuri de elemente în portofoliu.
Elemente intrare poate fi ascuns pentru că avem eticheta care va face toată treaba:
Intrare Ff-container(
afișaj: niciunul;
}
Acum să trecem la elementele listei:
Ff-articole(
poziție: relativă;
marjă: 0px automat;
padding-top: 20px;
}
Ff-articole a(
afisare: bloc;
poziție: relativă;
umplutură: 10px;
fundal : #fff ;
box-shadow: 0 1px 2px rgba(0 , 0 , 0 , 0.1 ) ;
marginea: 4px;
latime: 160px;
înălțime: 120px;
}
.ff-articole un interval (
afisare: bloc;
fundal: rgba(113, 123, 161, 0,9);
font-style: italic;
culoare : #fff ;
greutate font: bold;
umplutură: 20px;
poziție: absolută;
jos: 10px;
stânga: 10px;
lățime: 120px;
înălțime: 0px;
preaplin: ascuns;
opacitate: 0;
text-align: centru;
text-shadow : 1px 1px 1px #303857 ;
tranziție: toate 0.3s ease-in-out;
}
.ff-items a:hover span(
înălțime: 80px;
opacitate: 1;
}
.ff-items li img(
afisare: bloc;
}
Acestea sunt toate stilurile „generale”. Acum să ne uităm la stiluri pentru elementele de filtrare!
În primul exemplu, vom face ca elementele selectate (adică când butonul radio corespunzător este „bifat”) să aibă cea mai mare luminozitate.
Vom adăuga o tranziție la elementul listă pentru a crea opacitate:
Ff-articole li(
marja: 0px;
plutire: stânga;
opacitate: 0;
lățime: 188px;
înălțime: 148px;
tranziție: opacitate 0.6s ease-in-out;
}
Vom folosi apoi combinatorul generalizat de frați pentru a seta opacitatea elementelor corespunzătoare:
Ff-container input.ff-selector-type-all : verificat ~ .ff-items li,
opacitate: 1;
}
Deoarece toate butoanele radio sunt verificate inițial, toate elementele vor avea inițial o opacitate de 1.
Acum, vom folosi selectorul :not() pentru a specifica o listă de elemente care nu au o clasă selectată și ar trebui să aibă o opacitate de 0.1:
opacitate: 0,1;
}
Descrierile pentru aceste elemente din listă nu trebuie afișate la trecerea cursorului:
afișaj: niciunul;
}
Acesta a fost primul exemplu. Să aruncăm o privire la următorul.
În acest exemplu, vom mări elementele selectate, în timp ce altele vor fi mai mici și mai transparente. Deci, să adăugăm o tranziție la elementele din listă:
Ff-articole li(
marja: 0px;
plutire: stânga;
lățime: 188px;
înălțime: 148px;
tranziție: toate 0.6s ease-in-out;
}
În mod implicit, vom avea toate elementele din listă la dimensiunea normală și cu opacitate completă. Când selectăm un tip, dorim ca aceste articole să crească în dimensiune și, de asemenea, să rămână complet opace:
Ff-container input.ff-selector-type-1 : verificat ~ .ff-items .ff-item-type-1 ,
.ff-container input.ff-selector-type-2 : verificat ~ .ff-items .ff-item-type-2 ,
.ff-container input.ff-selector-type-3 : verificat ~ .ff-items .ff-item-type-3 (
opacitate: 1;
transforma: scară(1.1 ) ;
}
Vom reduce alte elemente de portofoliu și le vom aplica un nivel scăzut de transparență:
Ff-container input.ff-selector-type-1 : verificat ~ .ff-items li: not(.ff-item-type-1 ) ,
.ff-container input.ff-selector-type-2 : verificat ~ .ff-items li: not(.ff-item-type-2 ) ,
.ff-container input.ff-selector-type-3 : verificat ~ .ff-items li: not(.ff-item-type-3 ) (
opacitate: 0,1;
transforma: scară(0,5) ;
}
Și din nou vom ascunde descrierea pentru elementele care nu sunt selectate:
Ff-container input.ff-selector-type-1: verificat ~ .ff-items li: not(.ff-item-type-1 ) span,
.ff-container input.ff-selector-type-2 : verificat ~ .ff-items li: not(.ff-item-type-2 ) span,
.ff-container input.ff-selector-type-3 : verificat ~ .ff-items li: not(.ff-item-type-3 ) span(
afișaj: niciunul;
}
Ultimul exemplu este doar un experiment. Vrem să facem ceva mai complex aici: atunci când selectăm un tip, vrem să scalam toate elementele pentru a le face mai mici, apoi să mărim doar elementele cu tipul selectat.
Dorim ca elementele neselectate să dispară, dar din moment ce nu putem anima proprietatea de afișare, folosim un mic truc: când facem elementele mai mici, vom schimba lățimea la 0.
Deci, să setăm inițial lățimea listei la 0:
Ff-articole li(
marja: 0px;
plutire: stânga;
înălțime: 148px;
lățime: 0px;
transform: scale(0 , 0 ) ;
}
Când este selectat „toate”, vom schimba scara la 1 și vom seta lățimea la 188px:
Ff-container input.ff-selector-type-all : verificat ~ .ff-items li(
lățime: 188px;
transforma: scară(1 , 1 ) ;
tranziție: transformare 0,3s liniară;
}
Amintiți-vă că aceasta este starea inițială, deoarece avem „toate” bifate în mod implicit.
Acum, când marchem un anumit tip, elementele cu acel tip de clasă vor dispărea mai întâi împreună cu restul elementelor, apoi vor apărea din nou.
Ff-container input.ff-selector-type-1 : verificat ~ .ff-items .ff-item-type-1 ,
.ff-container input.ff-selector-type-2 : verificat ~ .ff-items .ff-item-type-2 ,
.ff-container input.ff-selector-type-3 : verificat ~ .ff-items .ff-item-type-3
{
tranziție: transformare 0,3s liniară, lățime 0s liniară 0,3s;
animație: scaleUp 0.3s liniar 0.4s înainte;
}
.ff-container input.ff-selector-type-1 : verificat ~ .ff-items li: not(.ff-item-type-1 ) ,
.ff-container input.ff-selector-type-2 : verificat ~ .ff-items li: not(.ff-item-type-2 ) ,
.ff-container input.ff-selector-type-3 : verificat ~ .ff-items li: not(.ff-item-type-3 )
{
animație: scaleDown 0.3s liniar înainte;
}
@keyframes scaleUp (
50% ( lățime : 188 px ; transformare: scară(0 , 0 ) ; )
100% ( lățime : 188 px ; transformare: scară(1 , 1 ) ; )
}
@keyframes scaleDown (
0% ( lățime : 188 px ; transformare: scară(1 , 1 ) ; )
99% ( lățime : 188 px ; transformare: scară(0 , 0 ) ; )
100% ( lățime : 0px ; transformare: scară(0 , 0 ) ; )
}
Vă rugăm să rețineți că acest exemplu este experimental și va funcționa corect numai în browserele care acceptă animația CSS. În Firefox 9.0.1, comportamentul nu este așa de așteptat (când treci cu mouse-ul peste etichetă, animația se declanșează din nou), dar totul funcționează în Aurora 11.0a2, deci poate că aceasta este o eroare a browserului.
Traducerea articolului de Mary Lou de pe tympanus.net/codropsDacă aveți întrebări, vă recomandăm să utilizați
Dar HTML acceptă și lucrul cu filtre. Aplicând diferite filtre textului, puteți obține efecte interesante. Dar Atenție, nu toate browserele afișează aceleași efecte pe care filtrele ar trebui să le ofere, unele browsere ignoră complet filtrele. Prin urmare, testați paginile dvs. web în browsere diferite. Toate filtrele funcționează corect în Internet Exhlorer. Deci, să vedem cum funcționează filtrele.
De exemplu, dorim să evidențiem fraza: "Bună ziua!!!„Să încercăm să răsturnăm această frază :-) aplicând diverse filtre.
Mască de filtrare.
Selectează textul, sau mai degrabă fundalul pe care este scris textul, ca și cum ai fi selectat textul cu mouse-ul.
Sintaxa filtrului: STYLE="filtru:Mască(Color="Color")
Culoare - culoarea de selecție în hexazecimal (de exemplu, #000FFF) sau numele culorii în engleză, de exemplu, Roșu, Albastru, Verde. Această definiție a culorii este utilizată în toate filtrele, astfel încât aceasta nu se va repeta în continuare.
Lista 19.1.
Filtru DropShadow.
Adaugă o umbră textului.
Sintaxa filtrului:
STYLE="filtru:DropShadow(Color="Color", OffX="Offx", OffY="Offy", Positive="Pozitive")"
Culoare - culoarea umbrei
OffX - Decalaj de umbră în X
OffY - Umbra Y offset
Pozitiv - Umbră stânga sau dreapta (0 sau respectiv 1)
Lista 19.3.
Așa arată pe pagina web:
Filtru FlipV.
Întoarce textul pe verticală.
Sintaxa filtrului: STYLE="filtru:FlipV"
Lista 19.5.
Așa arată pe pagina web:
Filtru de valuri.
Face textul ondulat.
Sintaxa filtrului:STYLE="filtru: Wave(Freq="Freq", Add="Add", LightStrength="LightStrength", Phase="Phase", Strength="Strength")"
Frecventa - numarul de unde
Adăugați - afișați/ascundeți chenarul (1 sau respectiv 0)
LightStrength - puterea undei
Fază - unghi de undă
Forța - intensitatea undei
Lista 19.7.
Bună ziua!!! |
Așa arată pe pagina web:
Filtru de estompare.
Estompează textul într-o anumită direcție.
Sintaxa filtrului:
STYLE="filtru:Blur(Add="Add", Direction="Direction", Strength="Strength")"
Adăugați - estompare moderată sau puternică (1 sau 0, respectiv)
Direcție - în ce direcție va apărea neclaritatea (de la 0 la 315)
Putere - compensare estompare
Am învățat cum să colectăm date despre client și să le trimitem la server. Și pe server au scris un stub în locul în care ar trebui returnate produsele filtrate după parametrii introduși. Acum vom scăpa de stub și vom scrie câteva metode și interogări care scot produsele necesare din baza de date și le returnează clientului. Lecția este destul de scurtă. Să începem
Ce vom face?
Trebuie să completăm doar 3 puncte:
- 1. Primiți date de la client și procesați-le pentru a se potrivi nevoilor serverului. De exemplu, setați parametrii impliciti
- 2. Scrieți, de fapt, codul în sine pentru a prelua produse din baza de date. În primul rând, pregătiți o interogare SQL
- 3. Returnați datele primite către client
Primirea datelor de la client
Vă puteți întreba: de ce trebuie să subliniați acest lucru operare simplă separat, dacă putem extrage cu ușurință toate datele din matricea $_GET?
În primul rând, pentru a seta valorile implicite.
În al doilea rând, nu toate datele sunt în $_GET într-o formă utilizabilă.
De exemplu, este mai convenabil pentru noi să trecem sortarea de la client cu un parametru sub forma field_direction, de exemplu, price_asc.
Dar într-o interogare sql acestea sunt entități separate, deci trebuie să fie preprocesate.
Situația este similară cu mărcile. Pe client, le trimitem ca o serie de mărci, iar php le primește și ca o matrice.
Dar pentru o interogare sql aveți nevoie de un șir - o listă de mărci separate prin virgule.
Prin urmare, mărcile trebuie să fie procesate în continuare.
Deci, să scriem o funcție getOptions() care va prelua date de la $_GET și le va converti într-un formular convenabil pentru noi.
Am oferit deja aproape toate informațiile introductive, așa că să ne uităm imediat la codul terminat.
// Obținerea datelor din funcția matrice _GET getOptions() ( // Categorie și prețuri $categoryId = (isset($_GET["categorie"])) ? (int)$_GET["categorie"] : 0; $minPrice = ( isset($_GET["min_price"])) ? (int)$_GET["min_price"] : 0 $maxPrice = (isset($_GET["max_price"])) ? (int)$_GET["max_price " ]: 1000000; // Mărci $brands = (isset($_GET["brands"])) ? implode($_GET["brands"], ",") : null; // Sortare $sort = (isset( $ _GET["sortare"])) ? $_GET["sortare"] : "preț_asc"; => $categoryId, "min_price" => $minPrice, "max_price" => $maxPrice, "sort_by" => $sortBy, "sort_dir" => $sortDir); Aici vedem că primim mai întâi id-ul categoriei., iar $conn este obiectul de conexiune la baza de date pe care l-am creat în lecția anterioară.
Sarcina noastră este să scriem o interogare SQL. In general arata asa:
Selectați g.id ca good_id, g.good ca bun, b.brand ca brand, g.price ca preț, g.rating ca rating, g.photo ca fotografie din bunuri ca g, brands ca b unde g.category_id = selectat_category și g.brand_id în (lista de mărci separate prin virgulă) și g.brand_id = b.id și (g.price între minimum_price și maximum_price) ordonați după sort_field sort_direction
Preluăm câmpurile de care avem nevoie aplicând o serie de condiții unde și specificând sortarea dorită.
Nu există probleme cu prețurile și sortarea, pur și simplu înlocuim valorile necesare în locurile corespunzătoare din cerere.
Dar trebuie să fii mai atent cu categoria și mărcile și iată de ce.
Fiecare produs pe care îl avem are întotdeauna o categorie.
Nu există un concept de categorie zero în baza noastră de date - am făcut acest lucru pentru confortul nostru, pentru a înțelege că utilizatorul din browser nu a selectat nicio categorie (sau a selectat toate - pentru noi este același lucru). Și în acest caz nu ar trebui să includem linia în cerere dacă nu există date.
Astfel, am primit o interogare SQL destul de sănătoasă, care ține cont de toate dorințele noastre.
Ultimele două linii execută această solicitare și returnează de la funcție o matrice de obiecte cu câmpurile necesare.
Rămâne doar să puneți totul cap la cap și să trimiteți bunurile primite înapoi clientului/browserului care deja așteaptă.
Returnam marfa clientului
Aceasta este cea mai ușoară parte a lecției.
Să ne uităm la ciotul scris în lecția anterioară.
// Conectare la baza de date $conn = connectDB();
// Returnează un răspuns de succes la client echo json_encode(array("code" => "succes", "data" => $_GET));
Să înlocuim acest cod cu
// Conectare la baza de date $conn = connectDB(); // Primesc date de la client $options = getOptions();// Obține bunuri $bunuri = getGoods($opțiuni, $conn);
// Returnează un răspuns de succes la client echo json_encode(array("code" => "succes", "options" => $opțiuni, "goods" => $goods));
Am adăugat câteva rânduri: funcția getOptions a preluat datele în variabila $opțiuni. L-am folosit imediat pentru a obține bunuri getGoods, rezultatele au fost salvate în $goods.Și am extins răspunsul către client. Parametrul de date a fost redenumit în opțiuni și nu i s-a returnat conținutul $_GET, ci valorile deja convertite.Și în parametrul bunuri, a fost returnată o serie de bunuri primite.
Un filtru bine conceput este un instrument puternic de care utilizatorii pot profita. De fapt, aceasta este o funcție importantă dacă site-ul tău (magazinul online) are o mulțime de produse distribuite în diferite categorii.
SURSE
Pentru comerțul electronic, este o modalitate de a crește ratele de conversie prin reducerea timpului necesar unui utilizator pentru a găsi ceea ce caută.
Crearea unor astfel de caracteristici nu este niciodată ușoară: filtrele depind în mare măsură de conținutul site-ului web; De asemenea, bara de filtrare nu trebuie să distragă atenția, concentrarea ar trebui să fie pusă pe conținut/produse. Așa că am încercat să vă facem viața puțin mai ușoară, creându-vă un panou de filtrare CSS extrem de personalizabil și ușor de integrat.
Profită de CSS Transitions, CSS Transformations și jQuery pentru tranziție lină dacă este necesar.
Crearea unei structuri
Structura HTML este puțin mai complexă decât de obicei. În primul rând, există două blocuri principale de conținut: antetul și elementele principale, al doilea este folosit pentru a include atât gallery.cd-gallery, cât și filter.cd-filter. În plus, avem o navigare imbricată (imbricată în 2 elemente div, datorită efectului dropdown vizibil pe dispozitive mobile) și filter trigger.cd-filter-trigger .
Este posibil să observați, de asemenea, o mulțime de nume de clasă (de exemplu, în articolele din lista de galerie) și filtre de date: acestea sunt folosite pentru filtrarea conținutului, nu pentru stil.
Nota. Scopul elementului .cd-gallery> li.gap este de a lucra în combinație cu text: justificare; Proprietate aplicată la .cd-gallery pentru a crea o grilă de galerie. Trebuie să creați cât mai multe elemente .gap cât numărul maxim de elemente dintr-un rând -1.
Filtru de conținut
Toate
Adăugarea unui stil
Majoritatea CSS se referă la elemente de formă de stil și alte decorațiuni de bază. Este interesant cum am definit și folosit unele clase - în combinație cu jQuery - pentru a schimba comportamentul unor elemente în funcție de anumite evenimente.
De exemplu: pe toate dispozitivele, bara de filtru se blochează când ajunge în partea de sus a ferestrei de vizualizare. Pentru a obține acest efect, am folosit clasa .is-fixed aplicată elementului principal (.cd-main-content) astfel încât să putem orienta câțiva dintre copiii acestuia. Mai exact: .cd-tab-filter-wrapper este într-o poziție statică, în timp ce .cd-filter și .cd-filter-trigger sunt într-o poziție absolută (față de .cd-main-content). Când aplicăm clasa .is-fixed la .cd-main-content , comutăm poziția tuturor acestor elemente la Fixed.
Cd-tab-filter-wrapper (culoare de fundal: #ffffff; z-index: 1; ) .cd-filter (poziție: absolut; sus: 0; stânga: 0; lățime: 280px; înălțime: 100%; fundal: #ffffff; z-index: translateX(-100%); .is-fixed .cd-tab-filter-wrapper (poziție: fix; sus: 0; stânga: 0; lățime: 100% ; ) .cd-main-content.is-fixed .cd-filter (poziția: fix; înălțime: 100vh; preaplin: ascuns ) .cd-main-content.is-fix .cd-filter-trigger (poziție: fix ; )
Un alt lucru care merită menționat este clasa .filter-is-visible. Se aplică mai multor elemente atunci când utilizatorul lansează panoul de filtrare. Pe toate dispozitivele, este folosit pentru a modifica valoarea translateX a elementului .cd-filter (de la -100% la 0). Pe dispozitive mai mari (>1170px) vizam, de asemenea, .cd-gallery și .cd-tab-filter și le reducem lățimea: astfel panoul nu se va suprapune pe conținut, iar utilizatorul va folosi caracteristici suplimentare Spațiu pentru aplicarea filtrelor și vizualizarea modificărilor în același timp, fără a fi nevoie să închideți panoul.
Gestionarea evenimentelor
Pentru a implementa funcționalitatea de filtrare a conținutului, am integrat pluginul MixItUp jQuery. Pentru a inițializa pluginul în containerul galeriei, folosim funcția mixItUp() și declarăm o variabilă buttonFilter care conține toate personalizate funcţionalitate filtra. În plus, folosim jQuery pentru a deschide/închide panoul de filtrare și a-l remedia (împreună cu navigarea cu file), astfel încât să apară în continuare atunci când derulați prin galerie.