СвойÑÑва навигаÑии по DOM Ñ Ð¾ÑоÑи, когда ÑлеменÑÑ ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ñ ÑÑдом. Ð ÑÑо, еÑли неÑ? Ðак полÑÑиÑÑ Ð¿ÑоизволÑнÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑÑÑаниÑÑ?
ÐÐ»Ñ ÑÑого в DOM еÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе меÑÐ¾Ð´Ñ Ð¿Ð¾Ð¸Ñка.
document.getElementById или пÑоÑÑо id
ÐÑли Ñ ÑлеменÑа еÑÑÑ Ð°ÑÑибÑÑ id, Ñо Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ ÐµÐ³Ð¾ вÑзовом document.getElementById(id), где Ð±Ñ Ð¾Ð½ ни наÑ
одилÑÑ.
ÐапÑимеÑ:
<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
// полÑÑиÑÑ ÑлеменÑ
let elem = document.getElementById('elem');
// ÑделаÑÑ ÐµÐ³Ð¾ Ñон кÑаÑнÑм
elem.style.background = 'red';
</script>
Также еÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»ÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼, ÑказаннÑм в id:
<div id="elem">
<div id="elem-content">ÐлеменÑ</div>
</div>
<script>
// elem - ÑÑÑлка на ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñ id="elem"
elem.style.background = 'red';
// внÑÑÑи id="elem-content" еÑÑÑ Ð´ÐµÑиÑ, Ñак ÑÑо Ñакой id не Ð¼Ð¾Ð¶ÐµÑ ÑлÑжиÑÑ Ð¸Ð¼ÐµÐ½ÐµÐ¼ пеÑеменной
// ...но Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ обÑаÑиÑÑÑÑ Ðº Ð½ÐµÐ¼Ñ ÑеÑез квадÑаÑнÑе Ñкобки: window['elem-content']
</script>
â¦Ðо ÑÑо ÑолÑко еÑли Ð¼Ñ Ð½Ðµ обÑÑвили в JavaScript пеÑеменнÑÑ Ñ Ñаким же именем, инаÑе она бÑÐ´ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¿ÑиоÑиÑеÑ:
<div id="elem"></div>
<script>
let elem = 5; // ÑепеÑÑ elem Ñавен 5, а не <div id="elem">
alert(elem); // 5
</script>
ÐÑо поведение ÑооÑвеÑÑÑвÑÐµÑ ÑÑандаÑÑÑ, но поддеÑживаеÑÑÑ Ð² оÑновном Ð´Ð»Ñ ÑовмеÑÑимоÑÑи, как оÑколок далÑкого пÑоÑлого.
ÐÑаÑÐ·ÐµÑ Ð¿ÑÑаеÑÑÑ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð½Ð°Ð¼, ÑмеÑÐ¸Ð²Ð°Ñ Ð¿ÑоÑÑÑанÑÑва имÑн JS и DOM. ÐÑо Ñдобно Ð´Ð»Ñ Ð¿ÑоÑÑÑÑ ÑкÑипÑов, коÑоÑÑе Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ Ð¿ÑÑмо в HTML, но, вообÑе говоÑÑ, не оÑÐµÐ½Ñ Ñ Ð¾ÑоÑо. ÐÐ¾Ð·Ð¼Ð¾Ð¶Ð½Ñ ÐºÐ¾Ð½ÑликÑÑ Ð¸Ð¼Ñн. ÐÑоме Ñого, пÑи ÑÑении JS-кода, не Ð²Ð¸Ð´Ñ HTML, непонÑÑно, оÑкÑда беÑÑÑÑÑ Ð¿ÐµÑеменнаÑ.
Ð ÑÑом ÑÑебнике Ð¼Ñ Ð±Ñдем обÑаÑаÑÑÑÑ Ðº ÑлеменÑам по id в пÑимеÑаÑ
Ð´Ð»Ñ ÐºÑаÑкоÑÑи, когда оÑевидно, оÑкÑда беÑÑÑÑÑ ÑлеменÑ.
Ð ÑеалÑной жизни лÑÑÑе иÑполÑзоваÑÑ document.getElementById.
id должно бÑÑÑ ÑникалÑнÑмÐнаÑение id должно бÑÑÑ ÑникалÑнÑм. РдокÑменÑе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑолÑко один ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñ Ð´Ð°Ð½Ð½Ñм id.
ÐÑли в докÑменÑе еÑÑÑ Ð½ÐµÑколÑко ÑлеменÑов Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñм знаÑением id, Ñо поведение меÑодов поиÑка непÑедÑказÑемо. ÐÑаÑÐ·ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð²ÐµÑнÑÑÑ Ð»Ñбой из ниÑ
ÑлÑÑайнÑм обÑазом. ÐоÑÑомÑ, пожалÑйÑÑа, пÑидеÑживайÑеÑÑ Ð¿Ñавила ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑникалÑноÑÑи id.
document.getElementById, а не anyElem.getElementByIdÐеÑод getElementById можно вÑзваÑÑ ÑолÑко Ð´Ð»Ñ Ð¾Ð±ÑекÑа document. Ðн оÑÑÑеÑÑвлÑÐµÑ Ð¿Ð¾Ð¸Ñк по id по вÑÐµÐ¼Ñ Ð´Ð¾ÐºÑменÑÑ.
querySelectorAll
СамÑй ÑнивеÑÑалÑнÑй меÑод поиÑка â ÑÑо elem.querySelectorAll(css), он возвÑаÑÐ°ÐµÑ Ð²Ñе ÑлеменÑÑ Ð²Ð½ÑÑÑи elem, ÑдовлеÑвоÑÑÑÑие Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ CSS-ÑелекÑоÑÑ.
СледÑÑÑий запÑÐ¾Ñ Ð¿Ð¾Ð»ÑÑÐ°ÐµÑ Ð²Ñе ÑлеменÑÑ <li>, коÑоÑÑе ÑвлÑÑÑÑÑ Ð¿Ð¾Ñледними поÑомками в <ul>:
<ul>
<li>ÐÑоÑ</li>
<li>ÑеÑÑ</li>
</ul>
<ul>
<li>полноÑÑÑÑ</li>
<li>пÑойден</li>
</ul>
<script>
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML); // "ÑеÑÑ", "пÑойден"
}
</script>
ÐÑÐ¾Ñ Ð¼ÐµÑод дейÑÑвиÑелÑно моÑнÑй, поÑÐ¾Ð¼Ñ ÑÑо можно иÑполÑзоваÑÑ Ð»Ñбой CSS-ÑелекÑоÑ.
ÐÑевдоклаÑÑÑ Ð² CSS-ÑелекÑоÑе, в ÑаÑÑноÑÑи :hover и :active, Ñакже поддеÑживаÑÑÑÑ. ÐапÑимеÑ, document.querySelectorAll(':hover') веÑнÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑÐ¸Ñ (в поÑÑдке вложенноÑÑи: Ð¾Ñ Ð²Ð½ÐµÑнего к внÑÑÑеннемÑ) из ÑекÑÑиÑ
ÑлеменÑов под кÑÑÑоÑом мÑÑи.
querySelector
ÐеÑод elem.querySelector(css) возвÑаÑÐ°ÐµÑ Ð¿ÐµÑвÑй ÑлеменÑ, ÑооÑвеÑÑÑвÑÑÑий Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ CSS-ÑелекÑоÑÑ.
ÐнаÑе говоÑÑ, ÑезÑлÑÑÐ°Ñ Ñакой же, как пÑи вÑзове elem.querySelectorAll(css)[0], но он ÑнаÑала найдÑÑ Ð²Ñе ÑлеменÑÑ, а поÑом возÑмÑÑ Ð¿ÐµÑвÑй, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº elem.querySelector найдÑÑ ÑолÑко пеÑвÑй и оÑÑановиÑÑÑ. ÐÑо бÑÑÑÑее, кÑоме Ñого, его коÑоÑе пиÑаÑÑ.
matches
ÐÑедÑдÑÑие меÑÐ¾Ð´Ñ Ð¸Ñкали по DOM.
ÐеÑод elem.matches(css) ниÑего не иÑеÑ, а пÑовеÑÑеÑ, ÑдовлеÑвоÑÑÐµÑ Ð»Ð¸ elem CSS-ÑелекÑоÑÑ, и возвÑаÑÐ°ÐµÑ true или false.
ÐÑÐ¾Ñ Ð¼ÐµÑод Ñдобен, когда Ð¼Ñ Ð¿ÐµÑебиÑаем ÑлеменÑÑ (напÑимеÑ, в маÑÑиве или в ÑÑм-Ñо подобном) и пÑÑаемÑÑ Ð²ÑбÑаÑÑ Ñе из Ð½Ð¸Ñ , коÑоÑÑе Ð½Ð°Ñ Ð¸Ð½ÑеÑеÑÑÑÑ.
ÐапÑимеÑ:
<a href="http://example.com/file.zip">...</a>
<a href="http://ya.ru">...</a>
<script>
// Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»ÑÐ±Ð°Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑÐ¸Ñ Ð²Ð¼ÐµÑÑо document.body.children
for (let elem of document.body.children) {
if (elem.matches('a[href$="zip"]')) {
alert("СÑÑлка на аÑÑ
ив: " + elem.href );
}
}
</script>
closest
ÐÑедки ÑлеменÑа â ÑодиÑелÑ, ÑодиÑÐµÐ»Ñ ÑодиÑелÑ, его ÑодиÑÐµÐ»Ñ Ð¸ Ñак далее. ÐмеÑÑе они обÑазÑÑÑ ÑепоÑÐºÑ Ð¸ÐµÑаÑÑ Ð¸Ð¸ Ð¾Ñ ÑлеменÑа до веÑÑинÑ.
ÐеÑод elem.closest(css) иÑÐµÑ Ð±Ð»Ð¸Ð¶Ð°Ð¹Ñего пÑедка, коÑоÑÑй ÑооÑвеÑÑÑвÑÐµÑ CSS-ÑелекÑоÑÑ. Сам ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñакже вклÑÑаеÑÑÑ Ð² поиÑк.
ÐÑÑгими Ñловами, меÑод closest поднимаеÑÑÑ Ð²Ð²ÐµÑÑ
Ð¾Ñ ÑлеменÑа и пÑовеÑÑÐµÑ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из ÑодиÑелей. ÐÑли он ÑооÑвеÑÑÑвÑÐµÑ ÑелекÑоÑÑ, поиÑк пÑекÑаÑаеÑÑÑ. ÐеÑод возвÑаÑÐ°ÐµÑ Ð»Ð¸Ð±Ð¾ пÑедка, либо null, еÑли Ñакой ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ найден.
ÐапÑимеÑ:
<h1>СодеÑжание</h1>
<div class="contents">
<ul class="book">
<li class="chapter">Ðлава 1</li>
<li class="chapter">Ðлава 2</li>
</ul>
</div>
<script>
let chapter = document.querySelector('.chapter'); // LI
alert(chapter.closest('.book')); // UL
alert(chapter.closest('.contents')); // DIV
alert(chapter.closest('h1')); // null (поÑÐ¾Ð¼Ñ ÑÑо h1 - не пÑедок)
</script>
getElementsBy*
СÑÑеÑÑвÑÑÑ Ñакже дÑÑгие меÑÐ¾Ð´Ñ Ð¿Ð¾Ð¸Ñка ÑлеменÑов по ÑегÑ, клаÑÑÑ Ð¸ Ñак далее.
Ðа даннÑй моменÑ, они ÑкоÑее иÑÑоÑиÑеÑкие, Ñак как querySelector более Ñем ÑÑÑекÑивен.
ÐдеÑÑ Ð¼Ñ ÑаÑÑмоÑÑим Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑ ÐºÐ°ÑÑинÑ, Ñакже Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе вÑÑÑеÑиÑÑ Ð¸Ñ Ð² ÑÑаÑом коде.
elem.getElementsByTagName(tag)иÑÐµÑ ÑлеменÑÑ Ñ Ð´Ð°Ð½Ð½Ñм Ñегом и возвÑаÑÐ°ÐµÑ Ð¸Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑиÑ. ÐеÑедав"*"вмеÑÑо Ñега, можно полÑÑиÑÑ Ð²ÑÐµÑ Ð¿Ð¾Ñомков.elem.getElementsByClassName(className)возвÑаÑÐ°ÐµÑ ÑлеменÑÑ, коÑоÑÑе имеÑÑ Ð´Ð°Ð½Ð½Ñй CSS-клаÑÑ.document.getElementsByName(name)возвÑаÑÐ°ÐµÑ ÑлеменÑÑ Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñм аÑÑибÑÑомname. ÐÑÐµÐ½Ñ Ñедко иÑполÑзÑеÑÑÑ.
ÐапÑимеÑ:
// полÑÑиÑÑ Ð²Ñе ÑлеменÑÑ div в докÑменÑе
let divs = document.getElementsByTagName('div');
ÐавайÑе найдÑм вÑе input в ÑаблиÑе:
<table id="table">
<tr>
<td>ÐÐ°Ñ Ð²Ð¾Ð·ÑаÑÑ:</td>
<td>
<label>
<input type="radio" name="age" value="young" checked> младÑе 18
</label>
<label>
<input type="radio" name="age" value="mature"> Ð¾Ñ 18 до 50
</label>
<label>
<input type="radio" name="age" value="senior"> ÑÑаÑÑе 60
</label>
</td>
</tr>
</table>
<script>
let inputs = table.getElementsByTagName('input');
for (let input of inputs) {
alert( input.value + ': ' + input.checked );
}
</script>
"s"!Ðдна из ÑамÑÑ
ÑаÑÑÑÑ
оÑибок наÑинаÑÑиÑ
ÑазÑабоÑÑиков (впÑоÑем, иногда и не ÑолÑко) â ÑÑо забÑÑÑ Ð±ÑÐºÐ²Ñ "s". То еÑÑÑ Ð¿ÑобоваÑÑ Ð²ÑзÑваÑÑ Ð¼ÐµÑод getElementByTagName вмеÑÑо getElementsByTagName.
ÐÑква "s" оÑÑÑÑÑÑвÑÐµÑ Ð² названии меÑода getElementById, Ñак как в данном ÑлÑÑае возвÑаÑÐ°ÐµÑ Ð¾Ð´Ð¸Ð½ ÑлеменÑ. Ðо getElementsByTagName веÑнÑÑ ÑпиÑок ÑлеменÑов, поÑÑÐ¾Ð¼Ñ "s" обÑзаÑелÑна.
ÐÑÑÐ³Ð°Ñ ÑаÑпÑоÑÑÑанÑÐ½Ð½Ð°Ñ Ð¾Ñибка â напиÑаÑÑ:
// не ÑабоÑаеÑ
document.getElementsByTagName('input').value = 5;
ÐопÑÑка пÑиÑвоиÑÑ Ð·Ð½Ð°Ñение коллекÑии, а не ÑлеменÑам внÑÑÑи неÑ, не ÑÑабоÑаеÑ.
ÐÑжно пеÑебÑаÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑÐ¸Ñ Ð² Ñикле или полÑÑиÑÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿Ð¾ номеÑÑ Ð¸ Ñже ÐµÐ¼Ñ Ð¿ÑиÑваиваÑÑ Ð·Ð½Ð°Ñение, напÑимеÑ, Ñак:
// ÑабоÑÐ°ÐµÑ (еÑли еÑÑÑ input)
document.getElementsByTagName('input')[0].value = 5;
ÐÑем ÑлеменÑÑ Ñ ÐºÐ»Ð°ÑÑом .article:
<form name="my-form">
<div class="article">Article</div>
<div class="long article">Long article</div>
</form>
<script>
// иÑем по имени аÑÑибÑÑа
let form = document.getElementsByName('my-form')[0];
// иÑем по клаÑÑÑ Ð²Ð½ÑÑÑи form
let articles = form.getElementsByClassName('article');
alert(articles.length); // 2, наÑ
одим два ÑлеменÑа Ñ ÐºÐ»Ð°ÑÑом article
</script>
ÐивÑе коллекÑии
ÐÑе меÑÐ¾Ð´Ñ "getElementsBy*" возвÑаÑаÑÑ Ð¶Ð¸Ð²ÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑиÑ. Такие коллекÑии вÑегда оÑÑажаÑÑ ÑекÑÑее ÑоÑÑоÑние докÑменÑа и авÑомаÑиÑеÑки обновлÑÑÑÑÑ Ð¿Ñи его изменении.
РпÑиведÑнном ниже пÑимеÑе еÑÑÑ Ð´Ð²Ð° ÑкÑипÑа.
- ÐеÑвÑй ÑоздаÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° коллекÑиÑ
<div>. Ðа ÑÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ ÐµÑ Ð´Ð»Ð¸Ð½Ð° Ñавна1. - ÐÑоÑой ÑкÑÐ¸Ð¿Ñ Ð·Ð°Ð¿ÑÑкаеÑÑÑ Ð¿Ð¾Ñле Ñого, как бÑаÑÐ·ÐµÑ Ð²ÑÑÑеÑÐ°ÐµÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½
<div>, ÑепеÑÑ ÐµÑ Ð´Ð»Ð¸Ð½Ð° â2.
<div>First div</div>
<script>
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 2
</script>
ÐапÑоÑив, querySelectorAll возвÑаÑÐ°ÐµÑ ÑÑаÑиÑеÑкÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑиÑ. ÐÑо поÑ
оже на ÑикÑиÑованнÑй маÑÑив ÑлеменÑов.
ÐÑли Ð¼Ñ Ð±Ñдем иÑполÑзоваÑÑ ÐµÐ³Ð¾ в пÑимеÑе вÑÑе, Ñо оба ÑкÑипÑа веÑнÑÑ Ð´Ð»Ð¸Ð½Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑии, ÑавнÑÑ 1:
<div>First div</div>
<script>
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 1
</script>
ТепеÑÑ Ð¼Ñ Ð»ÐµÐ³ÐºÐ¾ видим ÑазниÑÑ. Ðлина ÑÑаÑиÑеÑкой коллекÑии не изменилаÑÑ Ð¿Ð¾Ñле поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ div в докÑменÑе.
ÐÑого
ÐÑÑÑ 6 оÑновнÑÑ Ð¼ÐµÑодов поиÑка ÑлеменÑов в DOM:
| ÐеÑод | ÐÑÐµÑ Ð¿Ð¾... | ÐÑÐµÑ Ð²Ð½ÑÑÑи ÑлеменÑа? | ÐозвÑаÑÐ°ÐµÑ Ð¶Ð¸Ð²ÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑиÑ? |
querySelector |
CSS-selector | â | - |
querySelectorAll |
CSS-selector | â | - |
getElementById |
id |
- | - |
getElementsByName |
name |
- | â |
getElementsByTagName |
tag or '*' |
â | â |
getElementsByClassName |
class | â | â |
ÐезÑÑловно, наиболее ÑаÑÑо иÑполÑзÑемÑми в наÑÑоÑÑее вÑÐµÐ¼Ñ ÑвлÑÑÑÑÑ Ð¼ÐµÑÐ¾Ð´Ñ querySelector и querySelectorAll, но и меÑÐ¾Ð´Ñ getElement(s)By* могÑÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð² оÑделÑнÑÑ
ÑлÑÑаÑÑ
, а Ñакже вÑÑÑеÑаÑÑÑÑ Ð² ÑÑаÑом коде.
ÐÑоме Ñого:
- ÐÑÑÑ Ð¼ÐµÑод
elem.matches(css), коÑоÑÑй пÑовеÑÑеÑ, ÑдовлеÑвоÑÑÐµÑ Ð»Ð¸ ÑÐ»ÐµÐ¼ÐµÐ½Ñ CSS-ÑелекÑоÑÑ. - ÐеÑод
elem.closest(css)иÑÐµÑ Ð±Ð»Ð¸Ð¶Ð°Ð¹Ñего по иеÑаÑÑ Ð¸Ð¸ пÑедка, ÑооÑвеÑÑÑвÑÑÑÐµÐ¼Ñ Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ CSS-ÑелекÑоÑÑ. Сам ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñакже вклÑÑÑн в поиÑк.
Ð, напоÑледок, давайÑе ÑпомÑнем еÑÑ Ð¾Ð´Ð¸Ð½ меÑод, коÑоÑÑй пÑовеÑÑÐµÑ Ð½Ð°Ð»Ð¸Ñие оÑноÑений Ð¼ÐµÐ¶Ð´Ñ Ð¿Ñедком и поÑомком:
elemA.contains(elemB)веÑнÑÑtrue, еÑлиelemBÐ½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð²Ð½ÑÑÑиelemA(elemBпоÑомокelemA) или когдаelemA==elemB.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)