up
This commit is contained in:
parent
d991a8e1cd
commit
0c0487b630
4 changed files with 105 additions and 82 deletions
|
@ -1,27 +1,36 @@
|
||||||
Есть много вариантов решения, вот некоторые из них:
|
There are many ways to do it.
|
||||||
|
|
||||||
|
Here are some of them:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// 1
|
// 1. The table with `id="age-table"`.
|
||||||
document.getElementById('age-table').getElementsByTagName('label');
|
let table = document.getElementById('age-table')
|
||||||
|
|
||||||
// 2
|
// 2. All label elements inside that table
|
||||||
document.getElementById('age-table').getElementsByTagName('td')[0];
|
table.getElementsByTagName('label')
|
||||||
// в современных браузерах можно одним запросом:
|
// or
|
||||||
var result = document.querySelector('#age-table td');
|
document.querySelectorAll('#age-table label')
|
||||||
|
|
||||||
// 3
|
// 3. The first td in that table (with the word "Age").
|
||||||
document.getElementsByTagName('form')[1];
|
table.rows[0].cells[0]
|
||||||
|
// or
|
||||||
|
table.getElementsByTagName('td')[0]
|
||||||
|
// or
|
||||||
|
table.querySelector('td')
|
||||||
|
|
||||||
// 4
|
// 4. The form with the name "search".
|
||||||
document.querySelector('form[name="search"]');
|
// assuming there's only one element with name="search"
|
||||||
|
let form = document.getElementsByName('search')[0]
|
||||||
|
// or, form specifically
|
||||||
|
document.querySelector('form[name="search"]')
|
||||||
|
|
||||||
// 5
|
// 5. The first input in that form.
|
||||||
document.querySelector('form[name="search"] input')
|
form.getElementsByTagName('input')
|
||||||
|
// or
|
||||||
|
form.querySelector('input')
|
||||||
|
|
||||||
// 6
|
// 6. The last input in that form.
|
||||||
document.getElementsByName("info[0]")[0];
|
// there's no direct query for that
|
||||||
|
let inputs = form.querySelectorAll('input') // search all
|
||||||
// 7
|
inputs[inputs.length-1] // take last
|
||||||
document.querySelector('form[name="search-person"] [name="info[0]"]');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,32 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<form name="search">
|
<form name="search">
|
||||||
<label>Поиск по сайту:
|
<label>Search the site:
|
||||||
<input type="text" name="search">
|
<input type="text" name="search">
|
||||||
</label>
|
</label>
|
||||||
<input type="submit" value="Искать!">
|
<input type="submit" value="Search!">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<form name="search-person">
|
<form name="search-person">
|
||||||
Поиск по посетителям:
|
Search the visitors:
|
||||||
<table id="age-table">
|
<table id="age-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Возраст:</td>
|
<td>Age:</td>
|
||||||
<td id="age-list">
|
<td id="age-list">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="age" value="young">до 18</label>
|
<input type="radio" name="age" value="young">less than 18</label>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="age" value="mature">18-50</label>
|
<input type="radio" name="age" value="mature">18-50</label>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="age" value="senior">более 50</label>
|
<input type="radio" name="age" value="senior">more than 50</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Дополнительно:</td>
|
<td>Additionally:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="info[0]">
|
<input type="text" name="info[0]">
|
||||||
<input type="text" name="info[1]">
|
<input type="text" name="info[1]">
|
||||||
|
@ -41,8 +36,7 @@
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<input type="submit" value="Искать!">
|
<input type="submit" value="Search!">
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
</html>
|
||||||
</html>
|
|
||||||
|
|
|
@ -2,19 +2,17 @@ importance: 4
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Поиск элементов
|
# Search for elements
|
||||||
|
|
||||||
Ниже находится документ с таблицей и формой.
|
Here's the document with the table and form.
|
||||||
|
|
||||||
Найдите (получите в переменную) в нём:
|
How to find?
|
||||||
|
|
||||||
1. Все элементы `label` внутри таблицы. Должно быть 3 элемента.
|
1. The table with `id="age-table"`.
|
||||||
2. Первую ячейку таблицы (со словом `"Возраст"`).
|
2. All `label` elements inside that table (there should be 3 of them).
|
||||||
3. Вторую форму в документе.
|
3. The first `td` in that table (with the word "Age").
|
||||||
4. Форму с именем `search`, без использования её позиции в документе.
|
4. The `form` with the name `search`.
|
||||||
5. Элемент `input` в форме с именем `search`. Если их несколько, то нужен первый.
|
5. The first `input` in that form.
|
||||||
6. Элемент с именем `info[0]`, без точного знания его позиции в документе.
|
6. The last `input` in that form.
|
||||||
7. Элемент с именем `info[0]`, внутри формы с именем `search-person`.
|
|
||||||
|
|
||||||
Используйте для этого консоль браузера, открыв страницу [table.html](table.html) в отдельном окне.
|
|
||||||
|
|
||||||
|
Open the page [table.html](table.html) in a separate window and make use of browser tools for that.
|
||||||
|
|
|
@ -43,8 +43,8 @@ For instance:
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
```smart header="There must be only one"
|
```smart header="There can be only one"
|
||||||
By the specification the value of `id` must be unique. There may be only one element in the document with the given `id`.
|
By the specification the value of `id` must be unique. There can be only one element in the document with the given `id`.
|
||||||
|
|
||||||
If there are multiple elements with the same `id`, then the behavior is unpredictable. The browser may return any of them at random. So please stick to the rule and keep `id` unique.
|
If there are multiple elements with the same `id`, then the behavior is unpredictable. The browser may return any of them at random. So please stick to the rule and keep `id` unique.
|
||||||
```
|
```
|
||||||
|
@ -239,39 +239,62 @@ For instance:
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## XPath в современных браузерах
|
## Live collections
|
||||||
|
|
||||||
Для полноты картины рассмотрим ещё один способ поиска, который обычно используется в XML. Это <a href="http://www.w3.org/TR/xpath/">язык запросов XPath</a>.
|
All methods `getElementsBy*` return a *live* collection. They always reflect the current state of the document.
|
||||||
|
|
||||||
Он очень мощный, во многом мощнее CSS, но сложнее. Например, запрос для поиска элементов `H2`, содержащих текст `"XPath"`, будет выглядеть так: `//h2[contains(., "XPath")]`.
|
For instance, here in the first script the length is `1`, because the browser only processed the first div. Then later it's 2:
|
||||||
|
|
||||||
Все современные браузеры, кроме IE, поддерживают XPath с синтаксисом, близким к [описанному в MDN](https://developer.mozilla.org/en/XPath).
|
```html run
|
||||||
|
<div>First div</div>
|
||||||
|
|
||||||
Найдем заголовки с текстом `XPath` в текущем документе:
|
<script>
|
||||||
|
let divs = document.getElementsByTagName('div');
|
||||||
|
alert(divs.length); // 1
|
||||||
|
</script>
|
||||||
|
|
||||||
```js run no-beautify
|
<div>Second div</div>
|
||||||
var result = document.evaluate("//h2[contains(., 'XPath')]", document.documentElement, null,
|
|
||||||
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
||||||
|
|
||||||
for (var i = 0; i < result.snapshotLength; i++) {
|
<script>
|
||||||
alert( result.snapshotItem(i).outerHTML );
|
*!*
|
||||||
}
|
alert(divs.length); // 2
|
||||||
|
*/!*
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
IE тоже поддерживает XPath, но эта поддержка не соответствует стандарту и работает только для XML-документов, например, полученных с помощью `XMLHTTPRequest` (AJAX). Для обычных же HTML-документов XPath в IE не поддерживается.
|
In contrast, `querySelectorAll` returns a *static* collection. It's like a fixed array of elements.
|
||||||
|
|
||||||
Так как XPath сложнее и длиннее CSS, то используют его очень редко.
|
If we use it instead, then both scripts output `1`:
|
||||||
|
|
||||||
## Итого
|
|
||||||
|
|
||||||
Есть 6 основных методов поиска элементов DOM:
|
```html run
|
||||||
|
<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>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
There are 6 main methods to search for nodes in DOM:
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Метод</td>
|
<td>Method</td>
|
||||||
<td>Ищет по...</td>
|
<td>Finds by...</td>
|
||||||
<td>Ищет внутри элемента?</td>
|
<td>Can call on element?</td>
|
||||||
<td>Поддержка</td>
|
<td>Live?</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -279,45 +302,44 @@ IE тоже поддерживает XPath, но эта поддержка не
|
||||||
<td><code>getElementById</code></td>
|
<td><code>getElementById</code></td>
|
||||||
<td><code>id</code></td>
|
<td><code>id</code></td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>везде</td>
|
<td>-</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>getElementsByName</code></td>
|
<td><code>getElementsByName</code></td>
|
||||||
<td><code>name</code></td>
|
<td><code>name</code></td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>везде</td>
|
<td>✔</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>getElementsByTagName</code></td>
|
<td><code>getElementsByTagName</code></td>
|
||||||
<td>тег или <code>'*'</code></td>
|
<td>tag or <code>'*'</code></td>
|
||||||
|
<td>✔</td>
|
||||||
<td>✔</td>
|
<td>✔</td>
|
||||||
<td>везде</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>getElementsByClassName</code></td>
|
<td><code>getElementsByClassName</code></td>
|
||||||
<td>классу</td>
|
<td>class</td>
|
||||||
|
<td>✔</td>
|
||||||
<td>✔</td>
|
<td>✔</td>
|
||||||
<td>кроме IE8-</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>querySelector</code></td>
|
<td><code>querySelector</code></td>
|
||||||
<td>CSS-селектор</td>
|
<td>CSS-selector</td>
|
||||||
<td>✔</td>
|
<td>✔</td>
|
||||||
<td>везде</td>
|
<td>-</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>querySelectorAll</code></td>
|
<td><code>querySelectorAll</code></td>
|
||||||
<td>CSS-селектор</td>
|
<td>CSS-selector</td>
|
||||||
<td>✔</td>
|
<td>✔</td>
|
||||||
<td>везде</td>
|
<td>-</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
Практика показывает, что в 95% ситуаций достаточно `querySelector/querySelectorAll`. Хотя более специализированные методы `getElement*` работают чуть быстрее, но разница в миллисекунду-другую редко играет роль.
|
Please note that methods `getElementById` and `getElementsByName` can only be called in the context of the document: `document.getElementById(...)`. Other methods can be called on elements, like `elem.querySelectorAll(...)` -- and will search in their subtrees.
|
||||||
|
|
||||||
Кроме того:
|
Besides:
|
||||||
|
|
||||||
- Есть метод `elem.matches(css)`, который проверяет, удовлетворяет ли элемент CSS-селектору. Он поддерживается большинством браузеров в префиксной форме (`ms`, `moz`, `webkit`).
|
- There is `elem.matches(css)` to check if `elem` matches the given CSS selector.
|
||||||
- Метод `elem.closest(css)` ищет ближайший элемент выше по иерархии DOM, подходящий под CSS-селектор css. Сам элемент тоже включается в поиск.
|
- There is `elem.closest(css)` to look for a nearest ancestor that matches the given CSS-selector. The `elem` itself is also checked.
|
||||||
- Язык запросов XPath поддерживается большинством браузеров, кроме IE, даже 9-й версии, но `querySelector` удобнее. Поэтому XPath используется редко.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue