3.2.2 - A bemenet megadása
Röviden a szabványpontról
A WCAG 2.2 Success Criterion 3.2.2 (On Input) előírja, hogy amikor egy felhasználó egy felhasználói felület komponenssel lép kapcsolatba, amely megváltoztatja a tartalom kontextusát (például űrlap beküldése vagy opció kiválasztása), a változás csak azután következhet be, hogy a felhasználó befejezte a bevitelt és kifejezetten jelezte, hogy készen van. Ez azt jelenti, hogy a változások nem történhetnek meg automatikusan minden beviteli változásnál, például billentyűleütésnél vagy kiválasztás megváltoztatásánál, kivéve, ha a változás visszafordítható vagy a felhasználót előre figyelmeztetik.
Cél: Megelőzni a váratlan változásokat, amelyek összezavarhatják vagy megtévesztik a felhasználókat, különösen azokat, akik kisegítő technológiákat, vagy billentyűzetes navigációt használnak, azáltal, hogy biztosítjuk, hogy a felhasználók kontrollja alatt álljon az hogy, mikor történnek meg a változások.
Mire vonatkozik: Minden olyan felhasználói felület komponensre, amely a felhasználói interakció hatására kontextus változást okozhat, beleértve az űrlapokat, legördülő menüket, csúszkákat, és egyéb interaktív elemeket.
Kiket érint
Elsődleges felhasználók: Kognitív fogyatékossággal, motoros károsodással élő emberek, vagy azok, akik kisegítő technológiákat használnak, mint például képernyőolvasók és kizárólag billentyűzetes navigáció. Ezek a felhasználók nehezen boldogulnak a váratlan változásokkal, amelyek túl gyorsan, vagy világos felhasználói szándék nélkül történnek.
Másodlagos előnyök: Minden felhasználónak előnyös a véletlen változások megelőzése, és ezzel frusztráció csökkentése, valamint a felület kiszámíthatóságának és kontrolljának javítása révén.
Tesztelés
- Kizárólag billentyűzetes tesztelés: Navigálj a felületen csak a billentyűzet használatával és ellenőrizd, hogy a változások nem történnek meg automatikusan részleges bevitelnél, hanem csak a kifejezett műveletek után, mint például az Enter megnyomása vagy egy gomb kattintása
- Képernyőolvasó tesztelés: Használj képernyőolvasót az űrlap vezérlőkkel vagy widgetekkel való interakcióhoz és erősítsd meg, hogy a kontextus változások (mint oldal frissítések vagy tartalom újratöltések) csak felhasználói megerősítés után történnek
- Manuális beviteli tesztelés: Legördülő menük és csúszkák esetén ellenőrizd, hogy a felület csak akkor hajt-e végre változást, miután a felhasználó befejezte a bevitelt vagy kiválasztást.
- Automatizált tesztelő eszközök: Használj eszközöket, mint az axe DevTools a beviteli eseményekre váratlanul kiváltódó kontextus változásokkal kapcsolatos problémák észlelésére
- Felhasználói tesztelés kisegítő technológia felhasználókkal: Figyelj meg valós fogyatékossággal élő felhasználókat, hogy megbizonyosodj arról, hogy a felület kiszámíthatóan viselkedik és változások csak kifejezett felhasználói bevitel után történnek.
Jó gyakorlatok
1. Küldés gombok létrehozása az űrlapokhoz
<form>
<label for="email">E-mail cím:</label>
<input id="email" type="email" name="email" placeholder="pelda@email.hu">
<label for="nev">Teljes név:</label>
<input id="nev" type="text" name="nev" placeholder="Kovács János">
<label for="uzenet">Üzenet:</label>
<textarea id="uzenet" name="uzenet" placeholder="Írja ide üzenetét..."></textarea>
<!-- Csak felhasználói kattintás után küldi el -->
<button type="submit">Üzenet küldése</button>
</form>
<script>
// Helyes: várakozás a felhasználó kifejezett küldési szándékára
document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();
// Validálás és megerősítés
const email = document.getElementById('email').value;
const nev = document.getElementById('nev').value;
if (!email || !nev) {
alert('Kérjük, töltse ki az összes kötelező mezőt.');
return;
}
// Küldje el az űrlapot csak megerősítés után
if (confirm('Biztosan elküldi az üzenetet?')) {
console.log('Üzenet elküldve!');
// Itt történne a tényleges küldés
}
});
</script>
Magyarázat: Az űrlap csak akkor kerül elküldésre, amikor a felhasználó kifejezetten a „Küldés” gombra kattint, nem pedig a változást követően azonnal.
2. Legördülő menük megerősítő gombokkal
<div class="beallitas-panel">
<label for="nyelv">Válasszon nyelvet:</label>
<select id="nyelv" name="nyelv" aria-describedby="nyelv-info">
<option value="hu">Magyar</option>
<option value="en">English</option>
<option value="de">Deutsch</option>
<option value="fr">Français</option>
</select>
<div id="nyelv-info" class="info-szoveg">
A nyelv megváltoztatásához válasszon egy opciót, majd kattintson az Alkalmazás gombra.
</div>
<button type="button" onclick="nyelvBeallitas()" class="alkalmazas-gomb">
Nyelv alkalmazása
</button>
<button type="button" onclick="visszavonas()" class="visszavonas-gomb">
Mégse
</button>
</div>
<div class="termek-szuro">
<label for="kategoria">Termék kategória:</label>
<select id="kategoria" name="kategoria" aria-describedby="kategoria-info">
<option value="">Minden kategória</option>
<option value="elektronika">Elektronika</option>
<option value="ruhazkodas">Ruházat</option>
<option value="otthon">Otthon és kert</option>
<option value="sport">Sport és szabadidő</option>
</select>
<label for="ar-tartomany">Ár tartomány:</label>
<select id="ar-tartomany" name="ar-tartomany">
<option value="">Bármely ár</option>
<option value="0-10000">0 - 10.000 Ft</option>
<option value="10000-50000">10.000 - 50.000 Ft</option>
<option value="50000+">50.000 Ft felett</option>
</select>
<div id="kategoria-info" class="info-szoveg">
A szűrők alkalmazásához kattintson a "Szűrés" gombra.
</div>
<button type="button" onclick="szuresAlkalmazasa()" class="szures-gomb">
Termékek szűrése
</button>
</div>
<script>
function nyelvBeallitas() {
const valasztottNyelv = document.getElementById('nyelv').value;
// Megerősítés kérése
if (confirm(`Biztosan megváltoztatja a nyelvet erre: ${getNyelvNev(valasztottNyelv)}? Az oldal újra fog töltődni.`)) {
// Nyelv beállítása
localStorage.setItem('nyelv', valasztottNyelv);
// Felhasználó tájékoztatása
alert('Nyelv beállítva! Az oldal újra töltődik...');
// Oldal újratöltése
window.location.reload();
}
}
function getNyelvNev(kod) {
const nyelvek = {
'hu': 'Magyar',
'en': 'English',
'de': 'Deutsch',
'fr': 'Français'
};
return nyelvek[kod] || kod;
}
function visszavonas() {
// Eredeti érték visszaállítása
const eredetiNyelv = localStorage.getItem('nyelv') || 'hu';
document.getElementById('nyelv').value = eredetiNyelv;
alert('Változtatások visszavonva.');
}
function szuresAlkalmazasa() {
const kategoria = document.getElementById('kategoria').value;
const arTartomany = document.getElementById('ar-tartomany').value;
// Szűrési paraméterek összeállítása
let szuroFeltetelek = [];
if (kategoria) szuroFeltetelek.push(`Kategória: ${kategoria}`);
if (arTartomany) szuroFeltetelek.push(`Ár: ${arTartomany} Ft`);
if (szuroFeltetelek.length === 0) {
alert('Minden termék megjelenítése.');
} else {
alert(`Szűrés alkalmazva: ${szuroFeltetelek.join(', ')}`);
}
// Itt történne a tényleges szűrés
console.log('Szűrési feltételek:', {kategoria, arTartomany});
}
// Billentyűzet támogatás
document.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
const aktiv = document.activeElement;
// Ha select elemben vagyunk, ne alkalmazzuk automatikusan
if (aktiv.tagName === 'SELECT') {
e.preventDefault();
// Megfelelő alkalmazás gomb keresése
const szuloDiv = aktiv.closest('.beallitas-panel, .termek-szuro');
if (szuloDiv) {
const alkalmazasGomb = szuloDiv.querySelector('.alkalmazas-gomb, .szures-gomb');
if (alkalmazasGomb) {
alkalmazasGomb.focus();
}
}
}
}
});
</script>
<style>
.beallitas-panel, .termek-szuro {
border: 1px solid #ccc;
padding: 1rem;
margin: 1rem 0;
border-radius: 4px;
background: #f9f9f9;
}
.info-szoveg {
font-size: 0.9em;
color: #666;
margin: 0.5rem 0;
font-style: italic;
}
.alkalmazas-gomb, .szures-gomb {
background: #007bff;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
margin-right: 0.5rem;
}
.visszavonas-gomb {
background: #6c757d;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.alkalmazas-gomb:hover, .szures-gomb:hover {
background: #0056b3;
}
.visszavonas-gomb:hover {
background: #545b62;
}
select, button {
margin: 0.25rem;
padding: 0.5rem;
}
label {
display: block;
margin-top: 0.5rem;
font-weight: bold;
}
</style>
Magyarázat: A legördülő menük kiválasztása nem okoz azonnali változást; a felhasználónak kifejezetten meg kell nyomnia az „Alkalmazás” gombot a változtatások érvényesítéséhez.
3. Csúszkák és tartomány bevitelek kontrollált frissítéssel
<div class="hangeroszabo">
<label for="hangeroszabo-csuska">Hangerő beállítása:</label>
<div class="csuska-container">
<span class="hangeroszint">0</span>
<input
id="hangeroszabo-csuska"
type="range"
min="0"
max="100"
value="50"
aria-describedby="hangeroszint-info"
oninput="hangerosegElonezet(this.value)"
onchange="hangerosegBeallitas(this.value)"
>
<span class="hangeroszint">100</span>
</div>
<div id="hangeroszint-info" class="aktualis-ertek">
Jelenlegi hangerő: <span id="jelenlegi-hangeroszint">50</span>%
</div>
<div class="csuska-info">
A hangerő változtatása csak a csúszka elengedése után lép érvénybe.
</div>
</div>
<div class="ar-szuro">
<label for="ar-csuska">Maximális ár szűrő:</label>
<div class="csuska-container">
<span class="ar-cimke">0 Ft</span>
<input
id="ar-csuska"
type="range"
min="0"
max="500000"
step="10000"
value="100000"
aria-describedby="ar-info"
oninput="arElonezet(this.value)"
onchange="arSzuresBeallitas(this.value)"
>
<span class="ar-cimke">500.000 Ft</span>
</div>
<div id="ar-info" class="aktualis-ertek">
Kiválasztott maximális ár: <span id="jelenlegi-ar">100.000</span> Ft
</div>
<div class="csuska-info">
A termékek szűrése csak a csúszka elengedése után történik meg.
</div>
<button type="button" onclick="arSzuresAlkalmazas()" class="szures-alkalmazas">
Ár szűrő alkalmazása
</button>
</div>
<div class="kepernyo-fenyesseg">
<label for="fenyesseg-csuska">Képernyő fényerő:</label>
<div class="csuska-container">
<span class="fenyesseg-ikon">🔅</span>
<input
id="fenyesseg-csuska"
type="range"
min="10"
max="100"
value="75"
aria-describedby="fenyesseg-info"
oninput="fenyessegElonezet(this.value)"
onchange="fenyessegBeallitas(this.value)"
>
<span class="fenyesseg-ikon">🔆</span>
</div>
<div id="fenyesseg-info" class="aktualis-ertek">
Jelenlegi fényerő: <span id="jelenlegi-fenyesseg">75</span>%
</div>
<div class="visszavonas-opcio">
<button type="button" onclick="fenyessegVisszavonas()" class="visszavonas">
Eredeti fényerő visszaállítása
</button>
</div>
</div>
<script>
let eredetiHangeroszint = 50;
let eredetiAr = 100000;
let eredetiFenyesseg = 75;
let ideiglenesFenyesseg = 75;
// Hangerő előnézet (nem alkalmazza véglegesen)
function hangerosegElonezet(ertek) {
document.getElementById('jelenlegi-hangeroszint').textContent = ertek;
// Vizuális visszajelzés, hogy ez csak előnézet
const info = document.getElementById('hangeroszint-info');
info.style.fontStyle = 'italic';
info.style.color = '#666';
}
// Hangerő végleges beállítása (csak onchange eseménynél)
function hangerosegBeallitas(ertek) {
console.log(`Hangerő beállítva: ${ertek}%`);
// Visszajelzés, hogy a változás véglegesen alkalmazva lett
const info = document.getElementById('hangeroszint-info');
info.style.fontStyle = 'normal';
info.style.color = '#000';
// Megerősítő üzenet
announceChange(`Hangerő beállítva ${ertek} százalékra`);
}
// Ár előnézet
function arElonezet(ertek) {
document.getElementById('jelenlegi-ar').textContent = Number(ertek).toLocaleString('hu-HU');
const info = document.getElementById('ar-info');
info.style.fontStyle = 'italic';
info.style.color = '#666';
}
// Ár szűrés beállítása
function arSzuresBeallitas(ertek) {
console.log(`Ár szűrő előkészítve: ${ertek} Ft`);
const info = document.getElementById('ar-info');
info.style.fontStyle = 'normal';
info.style.color = '#000';
}
// Ár szűrő alkalmazása gombbal
function arSzuresAlkalmazas() {
const ertek = document.getElementById('ar-csuska').value;
console.log(`Ár szűrő alkalmazva: ${ertek} Ft`);
announceChange(`Termékek szűrve ${Number(ertek).toLocaleString('hu-HU')} forint maximum árral`);
}
// Fényerő előnézet
function fenyessegElonezet(ertek) {
ideiglenesFenyesseg = ertek;
document.getElementById('jelenlegi-fenyesseg').textContent = ertek;
// Vizuális előnézet alkalmazása
document.body.style.filter = `brightness(${ertek}%)`;
const info = document.getElementById('fenyesseg-info');
info.style.fontStyle = 'italic';
info.style.color = '#666';
}
// Fényerő végleges beállítása
function fenyessegBeallitas(ertek) {
eredetiFenyesseg = ertek;
console.log(`Fényerő véglegesen beállítva: ${ertek}%`);
const info = document.getElementById('fenyesseg-info');
info.style.fontStyle = 'normal';
info.style.color = '#000';
announceChange(`Képernyő fényerő beállítva ${ertek} százalékra`);
}
// Fényerő visszavonása
function fenyessegVisszavonas() {
document.getElementById('fenyesseg-csuska').value = eredetiFenyesseg;
document.getElementById('jelenlegi-fenyesseg').textContent = eredetiFenyesseg;
document.body.style.filter = `brightness(${eredetiFenyesseg}%)`;
announceChange(`Fényerő visszaállítva az eredeti ${eredetiFenyesseg} százalékra`);
}
// Képernyőolvasó értesítése változásokról
function announceChange(uzenet) {
const announcement = document.createElement('div');
announcement.setAttribute('role', 'status');
announcement.setAttribute('aria-live', 'polite');
announcement.className = 'sr-only';
announcement.textContent = uzenet;
document.body.appendChild(announcement);
setTimeout(() => {
if (announcement.parentNode) {
document.body.removeChild(announcement);
}
}, 1000);
}
// Billentyűzet támogatás csúszkákhoz
document.addEventListener('keydown', function(e) {
const aktiv = document.activeElement;
if (aktiv.type === 'range') {
// Arrow keys használatához ne legyen automatikus frissítés
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' ||
e.key === 'ArrowUp' || e.key === 'ArrowDown') {
// Csak értékfrissítés, nem végleges alkalmazás
setTimeout(() => {
const event = new Event('input');
aktiv.dispatchEvent(event);
}, 0);
}
// Enter vagy Space lenyomására véglegesítés
if (e.key === 'Enter' || e.key === ' ') {
const event = new Event('change');
aktiv.dispatchEvent(event);
}
}
});
</script>
<style>
.hangeroszabo, .ar-szuro, .kepernyo-fenyesseg {
border: 1px solid #ddd;
padding: 1.5rem;
margin: 1rem 0;
border-radius: 8px;
background: #f8f9fa;
}
.csuska-container {
display: flex;
align-items: center;
gap: 1rem;
margin: 1rem 0;
}
.csuska-container input[type="range"] {
flex: 1;
height: 6px;
background: #ddd;
border-radius: 3px;
outline: none;
}
.csuska-container input[type="range"]::-webkit-slider-thumb {
appearance: none;
width: 20px;
height: 20px;
background: #007bff;
border-radius: 50%;
cursor: pointer;
}
.csuska-container input[type="range"]::-moz-range-thumb {
width: 20px;
height: 20px;
background: #007bff;
border-radius: 50%;
cursor: pointer;
border: none;
}
.csuska-container input[type="range"]:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}
.aktualis-ertek {
font-size: 1.1em;
font-weight: bold;
margin: 0.5rem 0;
}
.csuska-info {
font-size: 0.9em;
color: #666;
margin-top: 0.5rem;
font-style: italic;
}
.szures-alkalmazas, .visszavonas {
background: #28a745;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
margin-top: 0.5rem;
}
.visszavonas {
background: #6c757d;
}
.szures-alkalmazas:hover {
background: #218838;
}
.visszavonas:hover {
background: #545b62;
}
.hangeroszint, .ar-cimke {
font-size: 0.9em;
color: #666;
min-width: 60px;
text-align: center;
}
.fenyesseg-ikon {
font-size: 1.2em;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
</style>
Magyarázat: A csúszkák mozgatása során csak előnézeti változtatásokat mutatunk, a végleges beállítás csak akkor történik meg, amikor a felhasználó befejezi a mozgatást (onchange esemény).
4. Visszavonás és megerősítés opciók biztosítása
<div class="beallitasok-panel">
<h2>Profil beállítások</h2>
<div class="beallitas-csoport">
<label for="ertesitesek">E-mail értesítések:</label>
<select id="ertesitesek" name="ertesitesek" onchange="ertesitesValtozas(this)">
<option value="mind">Minden értesítés</option>
<option value="fontos">Csak fontos értesítések</option>
<option value="nincs">Nincs értesítés</option>
</select>
</div>
<div class="beallitas-csoport">
<label for="tema">Weboldal témája:</label>
<select id="tema" name="tema" onchange="temaValtozas(this)">
<option value="vilagos">Világos téma</option>
<option value="sotet">Sötét téma</option>
<option value="automatikus">Automatikus</option>
</select>
</div>
<div class="beallitas-csoport">
<label for="nyelv">Felület nyelve:</label>
<select id="nyelv" name="nyelv" onchange="nyelvValtozas(this)">
<option value="hu">Magyar</option>
<option value="en">English</option>
<option value="de">Deutsch</option>
</select>
</div>
<!-- Visszavonás sáv -->
<div id="visszavonas-sav" class="visszavonas-sav elrejtett" role="alert" aria-live="polite">
<span class="visszavonas-uzenet"></span>
<div class="visszavonas-gombok">
<button type="button" onclick="valtozasVisszavonas()" class="visszavon-gomb">
Visszavonás
</button>
<button type="button" onclick="valtozasElfogadas()" class="elfogad-gomb">
Elfogadás
</button>
</div>
<div class="visszavonas-idozito">
<span class="idozito-szoveg">Automatikus elfogadás: <span id="idozito">10</span> másodperc</span>
<div class="progress-bar">
<div id="progress" class="progress-fill"></div>
</div>
</div>
</div>
</div>
<script>
let aktualisValtozas = null;
let visszavonasIdozito = null;
let progressIdozito = null;
let eredetiBeallitasok = {
ertesitesek: 'mind',
tema: 'vilagos',
nyelv: 'hu'
};
function ertesitesValtozas(select) {
beallitasValtozas('ertesitesek', select.value, 'E-mail értesítések');
}
function temaValtozas(select) {
beallitasValtozas('tema', select.value, 'Weboldal témája');
// Téma előnézet alkalmazása
alkalmazTemaElonezet(select.value);
}
function nyelvValtozas(select) {
beallitasValtozas('nyelv', select.value, 'Felület nyelve');
}
function beallitasValtozas(beallitasTipus, ujErtek, beallitasNev) {
const regiErtek = eredetiBeallitasok[beallitasTipus];
if (ujErtek === regiErtek) return; // Nincs változás
// Aktuális változás tárolása
aktualisValtozas = {
tipus: beallitasTipus,
regiErtek: regiErtek,
ujErtek: ujErtek,
nev: beallitasNev
};
// Visszavonás sáv megjelenítése
mutatVisszavonasSav();
// 10 másodperces időzítő indítása
inditsaIdozitot();
}
function mutatVisszavonasSav() {
const sav = document.getElementById('visszavonas-sav');
const uzenet = document.querySelector('.visszavonas-uzenet');
uzenet.textContent = `${aktualisValtozas.nev} megváltoztatva erre: "${getBeallitasNev(aktualisValtozas.tipus, aktualisValtozas.ujErtek)}"`;
sav.classList.remove('elrejtett');
sav.scrollIntoView({behavior: 'smooth'});
}
function getBeallitasNev(tipus, ertek) {
const nevMap = {
ertesitesek: {
'mind': 'Minden értesítés',
'fontos': 'Csak fontos értesítések',
'nincs': 'Nincs értesítés'
},
tema: {
'vilagos': 'Világos téma',
'sotet': 'Sötét téma',
'automatikus': 'Automatikus'
},
nyelv: {
'hu': 'Magyar',
'en': 'English',
'de': 'Deutsch'
}
};
return nevMap[tipus][ertek] || ertek;
}
function inditsaIdozitot() {
let maradekIdo = 10;
const idozitoSpan = document.getElementById('idozito');
const progress = document.getElementById('progress');
// Korábbi időzítők törlése
if (visszavonasIdozito) clearTimeout(visszavonasIdozito);
if (progressIdozito) clearInterval(progressIdozito);
// Progress bar frissítése
progressIdozito = setInterval(() => {
maradekIdo--;
idozitoSpan.textContent = maradekIdo;
progress.style.width = `${((10 - maradekIdo) / 10) * 100}%`;
if (maradekIdo <= 0) {
clearInterval(progressIdozito);
}
}, 1000);
// Automatikus elfogadás
visszavonasIdozito = setTimeout(() => {
valtozasElfogadas();
}, 10000);
}
function valtozasVisszavonas() {
if (!aktualisValtozas) return;
// Eredeti érték visszaállítása
const select = document.getElementById(aktualisValtozas.tipus);
select.value = aktualisValtozas.regiErtek;
// Téma esetén vizuális visszaállítás
if (aktualisValtozas.tipus === 'tema') {
alkalmazTemaElonezet(aktualisValtozas.regiErtek);
}
// Visszavonás sáv elrejtése
elrejtiVisszavonasSav();
// Képernyőolvasó értesítése
announceChange(`${aktualisValtozas.nev} visszavonva. Eredeti beállítás: ${getBeallitasNev(aktualisValtozas.tipus, aktualisValtozas.regiErtek)}`);
aktualisValtozas = null;
}
function valtozasElfogadas() {
if (!aktualisValtozas) return;
// Új érték mentése
eredetiBeallitasok[aktualisValtozas.tipus] = aktualisValtozas.ujErtek;
// Speciális kezelés nyelv változásnál
if (aktualisValtozas.tipus === 'nyelv') {
localStorage.setItem('nyelv', aktualisValtozas.ujErtek);
}
// Visszavonás sáv elrejtése
elrejtiVisszavonasSav();
// Képernyőolvasó értesítése
announceChange(`${aktualisValtozas.nev} elfogadva: ${getBeallitasNev(aktualisValtozas.tipus, aktualisValtozas.ujErtek)}`);
aktualisValtozas = null;
}
function elrejtiVisszavonasSav() {
const sav = document.getElementById('visszavonas-sav');
sav.classList.add('elrejtett');
// Időzítők törlése
if (visszavonasIdozito) {
clearTimeout(visszavonasIdozito);
visszavonasIdozito = null;
}
if (progressIdozito) {
clearInterval(progressIdozito);
progressIdozito = null;
}
// Progress bar visszaállítása
document.getElementById('progress').style.width = '0%';
document.getElementById('idozito').textContent = '10';
}
function alkalmazTemaElonezet(tema) {
const body = document.body;
// Témák eltávolítása
body.classList.remove('vilagos-tema', 'sotet-tema', 'automatikus-tema');
// Új téma alkalmazása
if (tema === 'sotet') {
body.classList.add('sotet-tema');
} else if (tema === 'automatikus') {
body.classList.add('automatikus-tema');
} else {
body.classList.add('vilagos-tema');
}
}
function announceChange(uzenet) {
const announcement = document.createElement('div');
announcement.setAttribute('role', 'status');
announcement.setAttribute('aria-live', 'polite');
announcement.className = 'sr-only';
announcement.textContent = uzenet;
document.body.appendChild(announcement);
setTimeout(() => {
if (announcement.parentNode) {
document.body.removeChild(announcement);
}
}, 1000);
}
// Oldal betöltésekor eredeti téma beállítása
document.addEventListener('DOMContentLoaded', function() {
alkalmazTemaElonezet(eredetiBeallitasok.tema);
});
</script>
<style>
.beallitasok-panel {
max-width: 600px;
margin: 2rem auto;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 8px;
background: white;
}
.beallitas-csoport {
margin: 1.5rem 0;
}
.beallitas-csoport label {
display: block;
font-weight: bold;
margin-bottom: 0.5rem;
}
.beallitas-csoport select {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
.visszavonas-sav {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 4px;
padding: 1rem;
margin-top: 1rem;
transition: all 0.3s ease;
}
.visszavonas-sav.elrejtett {
display: none;
}
.visszavonas-uzenet {
display: block;
font-weight: bold;
margin-bottom: 1rem;
}
.visszavonas-gombok {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.visszavon-gomb {
background: #dc3545;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.elfogad-gomb {
background: #28a745;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.visszavon-gomb:hover {
background: #c82333;
}
.elfogad-gomb:hover {
background: #218838;
}
.visszavonas-idozito {
font-size: 0.9em;
color: #666;
}
.progress-bar {
width: 100%;
height: 6px;
background: #e9ecef;
border-radius: 3px;
margin-top: 0.5rem;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: #007bff;
width: 0%;
transition: width 1s linear;
}
/* Témák */
.vilagos-tema {
background: white;
color: black;
}
.sotet-tema {
background: #333;
color: white;
}
.sotet-tema .beallitasok-panel {
background: #444;
border-color: #666;
color: white;
}
.sotet-tema .beallitas-csoport select {
background: #555;
color: white;
border-color: #666;
}
.automatikus-tema {
background: linear-gradient(to right, #f8f9fa, #e9ecef);
color: #333;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
</style>
Magyarázat: Azonnali változtatások esetén biztosítjuk a visszavonás lehetőségét és időt adunk a felhasználónak a módosítások átgondolására.
Helytelen megoldások
Automatikus űrlap beküldés minden beviteli változásnál
<form oninput="this.submit()">
<input type="text" name="kereses" placeholder="Keresés...">
</form>
<!-- Másik hibás példa -->
<form>
<input type="text" name="felhasznalonev" onkeyup="validateAndSubmit()">
<input type="password" name="jelszo" onkeyup="validateAndSubmit()">
</form>
Probléma: Az űrlap minden billentyűleütéskor elküldi magát, ami megzavarja a még gépelő felhasználókat és túlterheli a képernyőolvasókat.
Legördülő menük azonnali oldal frissítéssel
<select onchange="window.location.href=this.value;">
<option value="fooldal.html">Főoldal</option>
<option value="rolunk.html">Rólunk</option>
<option value="kapcsolat.html">Kapcsolat</option>
</select>
<!-- Másik hibás példa -->
<select onchange="document.location = this.options[this.selectedIndex].value;">
<option value="">Válasszon kategóriát</option>
<option value="?kategoria=elektronika">Elektronika</option>
<option value="?kategoria=ruhazat">Ruházat</option>
</select>
Probléma: Az oldal azonnal frissül a egy menüpont kiválasztáskor, ami összezavarja a csak billentyűzetet használó és képernyőolvasó felhasználókat, akik esetleg csak böngésznek az opciók között.
Csúszkák folyamatos frissítéssel
<input type="range" min="0" max="100" oninput="updateSettings(this.value)">
<script>
function updateSettings(value) {
// Hibás: minden apró mozdulatnál frissít
fetch('/api/settings', {
method: 'POST',
body: JSON.stringify({volume: value})
});
// Az oldal tartalma is változik minden mozdulatnál
document.getElementById('volume-display').innerHTML =
`<h2>Jelenlegi hangerő: ${value}</h2>`;
}
</script>
Probléma: A csúszka minden apró mozgatásánál frissítéseket küld, ami túlterheli mind a szervert, mind a kisegítő technológiákat használó felhasználókat.
Váratlan kontextus változások figyelmeztetés nélkül
<!-- Hibás: automatikus átirányítás időzítéssel -->
<script>
// Figyelmeztetés nélküli átirányítás 3 másodperc után
setTimeout(function() {
window.location.href = 'uj-oldal.html';
}, 3000);
</script>
<!-- Hibás: popupok jelennek meg input változáskor -->
<input type="email" oninput="showEmailSuggestions()">
<script>
function showEmailSuggestions() {
// Hibás: popup minden karakternél
if (event.target.value.length > 2) {
window.open('email-suggestions.html', '_blank');
}
}
</script>
Probléma: A felhasználók nincsenek felkészítve a váratlan kontextus változásokra, ami megtévesztő és zavaró lehet.
Hibás időzítések és automatikus műveletek
<!-- Hibás: túl gyors automatikus mentés -->
<textarea oninput="autoSave()"></textarea>
<script>
function autoSave() {
// Hibás: minden karakternél ment
fetch('/api/save', {
method: 'POST',
body: JSON.stringify({content: event.target.value})
}).then(() => {
// Hibás: zavaró értesítés minden mentésnél
alert('Automatikusan elmentve!');
});
}
// Hibás: túl agresszív keresés
let searchInput = document.getElementById('search');
searchInput.addEventListener('input', function() {
// Hibás: azonnal keres minden karakternél
performSearch(this.value);
});
function performSearch(query) {
if (query.length > 0) {
// Hibás: oldal tartalom azonnal változik
document.getElementById('results').innerHTML = 'Keresés folyamatban...';
fetch(`/search?q=${query}`)
.then(response => response.json())
.then(data => {
// Hibás: eredmények villognak minden karakternél
document.getElementById('results').innerHTML = data.html;
});
}
}
</script>
Probléma: A túl gyakori automatikus műveletek zavarják a felhasználói élményt és túlterhelik a kisegítő technológiákat.
Rossz hibakezelés beviteli események során
<form>
<input type="text" name="felhasznalo" oninput="validateUser(this.value)">
<input type="password" name="jelszo" oninput="validatePassword(this.value)">
</form>
<script>
function validateUser(value) {
if (value.length < 3) {
// Hibás: azonnali hibaüzenet gépelés közben
alert('A felhasználónév túl rövid!');
return;
}
// Hibás: API hívás minden karakternél
fetch(`/api/check-user/${value}`)
.then(response => {
if (!response.ok) {
// Hibás: hibaüzenet minden elírás esetén
alert('Ez a felhasználónév már foglalt!');
}
});
}
function validatePassword(value) {
// Hibás: folyamatos popup figyelmeztetések
if (!/[A-Z]/.test(value)) {
alert('Tartalmaznia kell nagybetűt!');
}
if (!/[0-9]/.test(value)) {
alert('Tartalmaznia kell számot!');
}
if (value.length < 8) {
alert('Legalább 8 karakter hosszú legyen!');
}
}
</script>
Probléma: A folyamatos validáció és hibaüzenetek megzavarják a felhasználókat gépelés közben, nem adnak lehetőséget a bevitel befejezésére.
Források
Iratkozz fel hírlevelünkre!
Amennyiben szeretnél első kézből értesülni az új bejegyzésekről, iratkozz fel hírlevelünkre!