ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾Ð»ÑÑÐ°ÐµÑ ÑокÑÑ, когда полÑзоваÑÐµÐ»Ñ ÐºÐ»Ð¸ÐºÐ°ÐµÑ Ð¿Ð¾ Ð½ÐµÐ¼Ñ Ð¸Ð»Ð¸ иÑполÑзÑÐµÑ ÐºÐ»Ð°Ð²Ð¸ÑÑ Tab. Также ÑÑÑеÑÑвÑÐµÑ HTML-аÑÑибÑÑ autofocus, коÑоÑÑй ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑокÑÑ Ð½Ð° ÑлеменÑ, когда ÑÑÑаниÑа загÑÑжаеÑÑÑ. ÐÑÑÑ Ð¸ дÑÑгие ÑпоÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑокÑÑа, о ниÑ
â далее.
ФокÑÑиÑовка обÑÑно ознаÑаеÑ: «пÑигоÑовÑÑÑ Ðº Ð²Ð²Ð¾Ð´Ñ Ð´Ð°Ð½Ð½ÑÑ Ð½Ð° ÑÑом ÑлеменÑе», ÑÑо Ñ Ð¾ÑоÑий моменÑ, ÑÑÐ¾Ð±Ñ Ð¸Ð½Ð¸ÑиализоваÑÑ Ð¸Ð»Ð¸ загÑÑзиÑÑ ÑÑо-нибÑдÑ.
ÐÐ¾Ð¼ÐµÐ½Ñ Ð¿Ð¾ÑеÑи ÑокÑÑа («blur») Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ð°Ð¶Ð½ÐµÐµ. ÐÑо моменÑ, когда полÑзоваÑÐµÐ»Ñ ÐºÐ»Ð¸ÐºÐ°ÐµÑ ÐºÑда-Ñо еÑÑ Ð¸Ð»Ð¸ Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ Tab, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑеклÑÑиÑÑÑÑ Ð½Ð° ÑледÑÑÑее поле ÑоÑмÑ. ÐÑÑÑ Ð´ÑÑгие пÑиÑÐ¸Ð½Ñ Ð¿Ð¾ÑеÑи ÑокÑÑа, о Ð½Ð¸Ñ â далее.
ÐоÑеÑÑ ÑокÑÑа обÑÑно ознаÑÐ°ÐµÑ Â«Ð´Ð°Ð½Ð½Ñе введенÑ», и Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ вÑполниÑÑ Ð¿ÑовеÑÐºÑ Ð²Ð²ÐµÐ´ÑннÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð¸Ð»Ð¸ даже оÑпÑавиÑÑ ÑÑи даннÑе на ÑеÑÐ²ÐµÑ Ð¸ Ñак далее.
Ð ÑабоÑе Ñ ÑобÑÑиÑми ÑокÑÑиÑовки еÑÑÑ Ð²Ð°Ð¶Ð½Ñе оÑобенноÑÑи. ÐÑ Ð¿Ð¾ÑÑаÑаемÑÑ ÑазобÑаÑÑ Ð¸Ñ Ð´Ð°Ð»ÐµÐµ.
СобÑÑÐ¸Ñ focus/blur
СобÑÑие focus вÑзÑваеÑÑÑ Ð² Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑокÑÑиÑовки, а blur â когда ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑеÑÑÐµÑ ÑокÑÑ.
ÐÑполÑзÑем Ð¸Ñ Ð´Ð»Ñ Ð²Ð°Ð»Ð¸Ð´Ð°Ñии(пÑовеÑки) введÑннÑÑ Ð´Ð°Ð½Ð½ÑÑ .
РпÑимеÑе ниже:
- ÐбÑабоÑÑик
blurпÑовеÑÑеÑ, введÑн ли email, и еÑли Ð½ÐµÑ â показÑÐ²Ð°ÐµÑ Ð¾ÑибкÑ. - ÐбÑабоÑÑик
focusÑкÑÑÐ²Ð°ÐµÑ ÑÑо ÑообÑение об оÑибке (в Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¿Ð¾ÑеÑи ÑокÑÑа пÑовеÑка повÑоÑиÑÑÑ):
<style>
.invalid { border-color: red; }
#error { color: red }
</style>
ÐÐ°Ñ email: <input type="email" id="input">
<div id="error"></div>
<script>
input.onblur = function() {
if (!input.value.includes('@')) { // не email
input.classList.add('invalid');
error.innerHTML = 'ÐожалÑйÑÑа, введиÑе пÑавилÑнÑй email.'
}
};
input.onfocus = function() {
if (this.classList.contains('invalid')) {
// ÑдалÑем индикаÑÐ¾Ñ Ð¾Ñибки, Ñ.к. полÑзоваÑÐµÐ»Ñ Ñ
оÑÐµÑ Ð²Ð²ÐµÑÑи даннÑе заново
this.classList.remove('invalid');
error.innerHTML = "";
}
};
</script>
СовÑеменнÑй HTML позволÑÐµÑ Ð´ÐµÐ»Ð°ÑÑ Ð²Ð°Ð»Ð¸Ð´Ð°ÑÐ¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð°ÑÑибÑÑов required, pattern и Ñ.д. Ðногда â ÑÑо вÑÑ, ÑÑо нам нÑжно. JavaScript можно иÑполÑзоваÑÑ, когда Ð¼Ñ Ñ
оÑим болÑÑе гибкоÑÑи. РеÑÑ Ð¼Ñ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ Ð¾ÑпÑавлÑÑÑ Ð¸Ð·Ð¼ÐµÐ½Ñнное знаÑение на ÑеÑвеÑ, еÑли оно пÑавилÑное.
ÐеÑÐ¾Ð´Ñ focus/blur
ÐеÑÐ¾Ð´Ñ elem.focus() и elem.blur() ÑÑÑанавливаÑÑ/ÑнимаÑÑ ÑокÑÑ.
ÐапÑимеÑ, запÑеÑим поÑеÑиÑÐµÐ»Ñ Ð¿ÐµÑеклÑÑаÑÑÑÑ Ñ Ð¿Ð¾Ð»Ñ Ð²Ð²Ð¾Ð´Ð°, еÑли введÑнное знаÑение не пÑоÑло валидаÑиÑ:
<style>
.error {
background: red;
}
</style>
ÐÐ°Ñ email: <input type="email" id="input">
<input type="text" style="width:280px" placeholder="введиÑе невеÑнÑй email и кликниÑе ÑÑда">
<script>
input.onblur = function() {
if (!this.value.includes('@')) { // не email
// показаÑÑ Ð¾ÑибкÑ
this.classList.add("error");
// ...и веÑнÑÑÑ ÑокÑÑ Ð¾Ð±ÑаÑно
input.focus();
} else {
this.classList.remove("error");
}
};
</script>
ÐÑо ÑÑабоÑÐ°ÐµÑ Ð²Ð¾ вÑÐµÑ Ð±ÑаÑзеÑÐ°Ñ , кÑоме Firefox (bug).
ÐÑли Ð¼Ñ ÑÑо-нибÑÐ´Ñ Ð²Ð²ÐµÐ´Ñм и нажмÑм Tab или кликнем в дÑÑгое меÑÑо, Ñогда onblur веÑнÑÑ ÑокÑÑ Ð¾Ð±ÑаÑно.
ÐÑмеÑим, ÑÑо Ð¼Ñ Ð½Ðµ можем «оÑмениÑÑ Ð¿Ð¾ÑеÑÑ ÑокÑÑа», вÑзвав event.preventDefault() в обÑабоÑÑике onblur поÑомÑ, ÑÑо onblur ÑÑабаÑÑÐ²Ð°ÐµÑ Ð¿Ð¾Ñле поÑеÑи ÑокÑÑа ÑлеменÑом.
Ðднако на пÑакÑике ÑледÑÐµÑ Ñ Ð¾ÑоÑо подÑмаÑÑ, пÑежде Ñем внедÑÑÑÑ ÑÑо-Ñо подобное, поÑÐ¾Ð¼Ñ ÑÑо Ð¼Ñ Ð¾Ð±ÑÑно Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑ Ð¾Ñибки полÑзоваÑелÑ, но они не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¼ÐµÑаÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¿Ñи заполнении наÑей ÑоÑмÑ. ÐедÑ, вполне возможно, ÑÑо он Ð·Ð°Ñ Ð¾ÑÐµÑ ÑнаÑала заполниÑÑ Ð´ÑÑгие полÑ.
ÐоÑеÑÑ ÑокÑÑа Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизойÑи по множеÑÑÐ²Ñ Ð¿ÑиÑин.
Ðдна из Ð½Ð¸Ñ â когда поÑеÑиÑÐµÐ»Ñ ÐºÐ»Ð¸ÐºÐ°ÐµÑ ÐºÑда-Ñо еÑÑ. Ðо и JavaScript Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑиÑиной, напÑимеÑ:
alertпеÑÐµÐ²Ð¾Ð´Ð¸Ñ ÑокÑÑ Ð½Ð° ÑÐµÐ±Ñ â ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑеÑÑÐµÑ ÑокÑÑ (ÑобÑÑиеblur), а когдаalertзакÑÑваеÑÑÑ â ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾Ð»ÑÑÐ°ÐµÑ ÑокÑÑ Ð¾Ð±ÑаÑно (ÑобÑÑиеfocus).- ÐÑли ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑдалиÑÑ Ð¸Ð· DOM, ÑокÑÑ Ñакже бÑÐ´ÐµÑ Ð¿Ð¾ÑеÑÑн. ÐÑли ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð¾Ð±ÑаÑно, Ñо ÑокÑÑ Ð½Ðµ веÑнÑÑÑÑ.
Ðз-за ÑÑиÑ
оÑобенноÑÑей обÑабоÑÑики focus/blur могÑÑ ÑÑабоÑаÑÑ Ñогда, когда ÑÑо не ÑÑебÑеÑÑÑ.
ÐÑполÑзÑÑ ÑÑи ÑобÑÑиÑ, нÑжно бÑÑÑ Ð¾ÑÑоÑожнÑм. ÐÑли Ð¼Ñ Ñ Ð¾Ñим оÑÑледиÑÑ Ð¿Ð¾ÑеÑÑ ÑокÑÑа, коÑоÑÑÑ Ð¸Ð½Ð¸ÑииÑовал полÑзоваÑелÑ, Ñогда нам ÑледÑÐµÑ Ð¸Ð·Ð±ÐµÐ³Ð°ÑÑ ÐµÑ Ñамим.
ÐклÑÑаем ÑокÑÑиÑÐ¾Ð²ÐºÑ Ð½Ð° лÑбом ÑлеменÑе: tabindex
Ðногие ÑлеменÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ðµ поддеÑживаÑÑ ÑокÑÑиÑовкÑ.
Ðакие именно â завиÑÐ¸Ñ Ð¾Ñ Ð±ÑаÑзеÑа, но одно вÑегда веÑно: поддеÑжка focus/blur гаÑанÑиÑована Ð´Ð»Ñ ÑлеменÑов, Ñ ÐºÐ¾ÑоÑÑми поÑеÑиÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð´ÐµÐ¹ÑÑвоваÑÑ: <button>, <input>, <select>, <a> и Ñ.д.
С дÑÑгой ÑÑоÑонÑ, ÑлеменÑÑ ÑоÑмаÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ <div>, <span>, <table> â по ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ðµ могÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÑокÑÑ. ÐеÑод elem.focus() не ÑабоÑÐ°ÐµÑ Ð´Ð»Ñ Ð½Ð¸Ñ
, и ÑобÑÑÐ¸Ñ focus/blur никогда не ÑÑабаÑÑваÑÑ.
ÐÑо можно измениÑÑ HTML-аÑÑибÑÑом tabindex.
ÐÑбой ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑокÑÑиÑовкÑ, еÑли Ð¸Ð¼ÐµÐµÑ tabindex. ÐнаÑение ÑÑого аÑÑибÑÑа â поÑÑдковÑй Ð½Ð¾Ð¼ÐµÑ ÑлеменÑа, когда клавиÑа Tab (или ÑÑо-Ñо аналогиÑное) иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð¿ÐµÑеклÑÑÐµÐ½Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñ ÑлеменÑами.
То еÑÑÑ: еÑли Ñ Ð½Ð°Ñ Ð´Ð²Ð° ÑлеменÑа, пеÑвÑй Ð¸Ð¼ÐµÐµÑ tabindex="1", а вÑоÑой tabindex="2", Ñо наÑ
одÑÑÑ Ð² пеÑвом ÑлеменÑе и нажав Tab â Ð¼Ñ Ð¿ÐµÑемеÑÑимÑÑ Ð²Ð¾ вÑоÑой.
ÐоÑÑдок пеÑебоÑа Ñаков: ÑнаÑала идÑÑ ÑлеменÑÑ Ñо знаÑениÑми tabindex Ð¾Ñ 1 и вÑÑе, в поÑÑдке tabindex, а заÑем ÑлеменÑÑ Ð±ÐµÐ· tabindex (напÑимеÑ, обÑÑнÑй <input>).
ÐÑи ÑовпадаÑÑиÑ
tabindex ÑлеменÑÑ Ð¿ÐµÑебиÑаÑÑÑÑ Ð² Ñом поÑÑдке, в коÑоÑом идÑÑ Ð² докÑменÑе.
ÐÑÑÑ Ð´Ð²Ð° ÑпеÑиалÑнÑÑ Ð·Ð½Ð°ÑениÑ:
-
tabindex="0"ÑÑÐ°Ð²Ð¸Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² один ÑÑд Ñ ÑлеменÑами безtabindex. То еÑÑÑ, пÑи пеÑеклÑÑении Ñакие ÑлеменÑÑ Ð±ÑдÑÑ Ð¿Ð¾Ñле ÑлеменÑов Ñtabindex ⥠1.ÐбÑÑно иÑполÑзÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð²ÐºÐ»ÑÑиÑÑ ÑокÑÑиÑÐ¾Ð²ÐºÑ Ð½Ð° ÑлеменÑе, но не менÑÑÑ Ð¿Ð¾ÑÑдок пеÑеклÑÑениÑ. ЧÑÐ¾Ð±Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð¾Ð³ ÑÑаÑÑвоваÑÑ Ð² ÑоÑме наÑавне Ñ Ð¾Ð±ÑÑнÑми
<input>. -
tabindex="-1"позволÑÐµÑ ÑокÑÑиÑоваÑÑÑÑ Ð½Ð° ÑлеменÑе ÑолÑко пÑогÑаммно. ÐлавиÑа Tab пÑоигноÑиÑÑÐµÑ Ñакой ÑлеменÑ, но меÑодelem.focus()бÑÐ´ÐµÑ Ð´ÐµÐ¹ÑÑвоваÑÑ.
ÐапÑимеÑ, ÑпиÑок ниже. ÐликниÑе пеÑвÑй пÑÐ½ÐºÑ Ð² ÑпиÑке и нажмиÑе Tab:
ÐликниÑе пеÑвÑй пÑÐ½ÐºÑ Ð² ÑпиÑке и нажмиÑе Tab. ÐÑодолжайÑе ÑледиÑÑ Ð·Ð° поÑÑдком. ÐбÑаÑиÑе внимание, ÑÑо много поÑледоваÑелÑнÑÑ
нажаÑий Tab могÑÑ Ð²ÑвеÑÑи ÑокÑÑ Ð¸Ð· iframe Ñ Ð¿ÑимеÑом.
<ul>
<li tabindex="1">Ðдин</li>
<li tabindex="0">ÐолÑ</li>
<li tabindex="2">Ðва</li>
<li tabindex="-1">ÐинÑÑ Ð¾Ð´Ð¸Ð½</li>
</ul>
<style>
li { cursor: pointer; }
:focus { outline: 1px dashed green; }
</style>
ÐоÑÑдок Ñакой: 1 - 2 - 0. ÐбÑÑно <li> не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑокÑÑиÑовкÑ, но tabindex вклÑÑÐ°ÐµÑ ÐµÑ, а Ñакже ÑобÑÑÐ¸Ñ Ð¸ ÑÑилизаÑÐ¸Ñ Ð¿ÑевдоклаÑÑом :focus.
elem.tabIndex Ñоже ÑабоÑаеÑÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ добавиÑÑ tabindex из JavaScript, иÑполÑзÑÑ ÑвойÑÑво elem.tabIndex. ÐÑо даÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑÑÑекÑ.
СобÑÑÐ¸Ñ focusin/focusout
СобÑÑÐ¸Ñ focus и blur не вÑплÑваÑÑ.
ÐапÑимеÑ, Ð¼Ñ Ð½Ðµ можем иÑполÑзоваÑÑ onfocus на <form>, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð´ÑвеÑиÑÑ ÐµÑ:
<!-- добавиÑÑ ÐºÐ»Ð°ÑÑ Ð¿Ñи ÑокÑÑиÑовке на ÑоÑме -->
<form onfocus="this.className='focused'">
<input type="text" name="name" value="ÐмÑ">
<input type="text" name="surname" value="ФамилиÑ">
</form>
<style> .focused { outline: 1px solid red; } </style>
ÐÑÐ¸Ð¼ÐµÑ Ð²ÑÑе не ÑабоÑаеÑ, поÑÐ¾Ð¼Ñ ÑÑо когда полÑзоваÑÐµÐ»Ñ Ð¿ÐµÑемеÑÐ°ÐµÑ ÑокÑÑ Ð½Ð° <input>, ÑобÑÑие focus ÑÑабаÑÑÐ²Ð°ÐµÑ ÑолÑко на ÑÑом ÑлеменÑе. ÐÑо ÑобÑÑие не вÑплÑваеÑ. СледоваÑелÑно, form.onfocus никогда не ÑÑабаÑÑваеÑ.
У ÑÑой пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð´Ð²Ð° ÑеÑениÑ.
ÐеÑвое: Ð·Ð°Ð±Ð°Ð²Ð½Ð°Ñ Ð¾ÑобенноÑÑÑ â focus/blur не вÑплÑваÑÑ, но пеÑедаÑÑÑÑ Ð²Ð½Ð¸Ð· на Ñазе пеÑеÑ
ваÑа.
ÐÑо ÑÑабоÑаеÑ:
<form id="form">
<input type="text" name="name" value="ÐмÑ">
<input type="text" name="surname" value="ФамилиÑ">
</form>
<style> .focused { outline: 1px solid red; } </style>
<script>
// ÑÑÑановиÑÑ Ð¾Ð±ÑабоÑÑик на Ñазе пеÑеÑ
ваÑа (поÑледний аÑгÑÐ¼ÐµÐ½Ñ true)
form.addEventListener("focus", () => form.classList.add('focused'), true);
form.addEventListener("blur", () => form.classList.remove('focused'), true);
</script>
ÐÑоÑое ÑеÑение: ÑобÑÑÐ¸Ñ focusin и focusout â Ñакие же, как и focus/blur, но они вÑплÑваÑÑ.
ÐамеÑÑÑе, ÑÑо ÑÑи ÑобÑÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑÑÑ Ñ elem.addEventListener, но не Ñ on<event>.
ÐÑоÑой ÑабоÑий ваÑианÑ:
<form id="form">
<input type="text" name="name" value="ÐмÑ">
<input type="text" name="surname" value="ФамилиÑ">
</form>
<style> .focused { outline: 1px solid red; } </style>
<script>
form.addEventListener("focusin", () => form.classList.add('focused'));
form.addEventListener("focusout", () => form.classList.remove('focused'));
</script>
ÐÑого
СобÑÑÐ¸Ñ focus и blur ÑÑабаÑÑваÑÑ Ð½Ð° ÑокÑÑиÑовке/поÑеÑе ÑокÑÑа ÑлеменÑа.
ÐÑ Ð¾ÑобенноÑÑи:
- Ðни не вÑплÑваÑÑ. Ðо можно иÑполÑзоваÑÑ ÑÐ°Ð·Ñ Ð¿ÐµÑеÑ
ваÑа или
focusin/focusout. - ÐолÑÑинÑÑво ÑлеменÑов не поддеÑживаÑÑ ÑокÑÑиÑÐ¾Ð²ÐºÑ Ð¿Ð¾ ÑмолÑаниÑ. ÐÑполÑзÑйÑе
tabindex, ÑÑÐ¾Ð±Ñ ÑделаÑÑ ÑокÑÑиÑÑемÑм лÑбой ÑлеменÑ.
ТекÑÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñ ÑокÑÑом можно полÑÑиÑÑ Ð¸Ð· document.activeElement.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)