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
|
||||
// 1
|
||||
document.getElementById('age-table').getElementsByTagName('label');
|
||||
// 1. The table with `id="age-table"`.
|
||||
let table = document.getElementById('age-table')
|
||||
|
||||
// 2
|
||||
document.getElementById('age-table').getElementsByTagName('td')[0];
|
||||
// в современных браузерах можно одним запросом:
|
||||
var result = document.querySelector('#age-table td');
|
||||
// 2. All label elements inside that table
|
||||
table.getElementsByTagName('label')
|
||||
// or
|
||||
document.querySelectorAll('#age-table label')
|
||||
|
||||
// 3
|
||||
document.getElementsByTagName('form')[1];
|
||||
// 3. The first td in that table (with the word "Age").
|
||||
table.rows[0].cells[0]
|
||||
// or
|
||||
table.getElementsByTagName('td')[0]
|
||||
// or
|
||||
table.querySelector('td')
|
||||
|
||||
// 4
|
||||
document.querySelector('form[name="search"]');
|
||||
// 4. The form with the 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
|
||||
document.querySelector('form[name="search"] input')
|
||||
// 5. The first input in that form.
|
||||
form.getElementsByTagName('input')
|
||||
// or
|
||||
form.querySelector('input')
|
||||
|
||||
// 6
|
||||
document.getElementsByName("info[0]")[0];
|
||||
|
||||
// 7
|
||||
document.querySelector('form[name="search-person"] [name="info[0]"]');
|
||||
// 6. The last input in that form.
|
||||
// there's no direct query for that
|
||||
let inputs = form.querySelectorAll('input') // search all
|
||||
inputs[inputs.length-1] // take last
|
||||
```
|
||||
|
||||
|
|
|
@ -1,37 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form name="search">
|
||||
<label>Поиск по сайту:
|
||||
<label>Search the site:
|
||||
<input type="text" name="search">
|
||||
</label>
|
||||
<input type="submit" value="Искать!">
|
||||
<input type="submit" value="Search!">
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<form name="search-person">
|
||||
Поиск по посетителям:
|
||||
Search the visitors:
|
||||
<table id="age-table">
|
||||
<tr>
|
||||
<td>Возраст:</td>
|
||||
<td>Age:</td>
|
||||
<td id="age-list">
|
||||
<label>
|
||||
<input type="radio" name="age" value="young">до 18</label>
|
||||
<input type="radio" name="age" value="young">less than 18</label>
|
||||
<label>
|
||||
<input type="radio" name="age" value="mature">18-50</label>
|
||||
<label>
|
||||
<input type="radio" name="age" value="senior">более 50</label>
|
||||
<input type="radio" name="age" value="senior">more than 50</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Дополнительно:</td>
|
||||
<td>Additionally:</td>
|
||||
<td>
|
||||
<input type="text" name="info[0]">
|
||||
<input type="text" name="info[1]">
|
||||
|
@ -41,8 +36,7 @@
|
|||
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Искать!">
|
||||
<input type="submit" value="Search!">
|
||||
</form>
|
||||
</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 элемента.
|
||||
2. Первую ячейку таблицы (со словом `"Возраст"`).
|
||||
3. Вторую форму в документе.
|
||||
4. Форму с именем `search`, без использования её позиции в документе.
|
||||
5. Элемент `input` в форме с именем `search`. Если их несколько, то нужен первый.
|
||||
6. Элемент с именем `info[0]`, без точного знания его позиции в документе.
|
||||
7. Элемент с именем `info[0]`, внутри формы с именем `search-person`.
|
||||
|
||||
Используйте для этого консоль браузера, открыв страницу [table.html](table.html) в отдельном окне.
|
||||
1. The table with `id="age-table"`.
|
||||
2. All `label` elements inside that table (there should be 3 of them).
|
||||
3. The first `td` in that table (with the word "Age").
|
||||
4. The `form` with the name `search`.
|
||||
5. The first `input` in that form.
|
||||
6. The last `input` in that form.
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
```smart header="There must 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`.
|
||||
```smart header="There can be only one"
|
||||
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.
|
||||
```
|
||||
|
@ -239,39 +239,62 @@ For instance:
|
|||
</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
|
||||
var result = document.evaluate("//h2[contains(., 'XPath')]", document.documentElement, null,
|
||||
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||
<div>Second div</div>
|
||||
|
||||
for (var i = 0; i < result.snapshotLength; i++) {
|
||||
alert( result.snapshotItem(i).outerHTML );
|
||||
}
|
||||
<script>
|
||||
*!*
|
||||
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>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Метод</td>
|
||||
<td>Ищет по...</td>
|
||||
<td>Ищет внутри элемента?</td>
|
||||
<td>Поддержка</td>
|
||||
<td>Method</td>
|
||||
<td>Finds by...</td>
|
||||
<td>Can call on element?</td>
|
||||
<td>Live?</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -279,45 +302,44 @@ IE тоже поддерживает XPath, но эта поддержка не
|
|||
<td><code>getElementById</code></td>
|
||||
<td><code>id</code></td>
|
||||
<td>-</td>
|
||||
<td>везде</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>getElementsByName</code></td>
|
||||
<td><code>name</code></td>
|
||||
<td>-</td>
|
||||
<td>везде</td>
|
||||
<td>✔</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>getElementsByTagName</code></td>
|
||||
<td>тег или <code>'*'</code></td>
|
||||
<td>tag or <code>'*'</code></td>
|
||||
<td>✔</td>
|
||||
<td>✔</td>
|
||||
<td>везде</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>getElementsByClassName</code></td>
|
||||
<td>классу</td>
|
||||
<td>class</td>
|
||||
<td>✔</td>
|
||||
<td>✔</td>
|
||||
<td>кроме IE8-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>querySelector</code></td>
|
||||
<td>CSS-селектор</td>
|
||||
<td>CSS-selector</td>
|
||||
<td>✔</td>
|
||||
<td>везде</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>querySelectorAll</code></td>
|
||||
<td>CSS-селектор</td>
|
||||
<td>CSS-selector</td>
|
||||
<td>✔</td>
|
||||
<td>везде</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</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`).
|
||||
- Метод `elem.closest(css)` ищет ближайший элемент выше по иерархии DOM, подходящий под CSS-селектор css. Сам элемент тоже включается в поиск.
|
||||
- Язык запросов XPath поддерживается большинством браузеров, кроме IE, даже 9-й версии, но `querySelector` удобнее. Поэтому XPath используется редко.
|
||||
- There is `elem.matches(css)` to check if `elem` matches the given CSS selector.
|
||||
- There is `elem.closest(css)` to look for a nearest ancestor that matches the given CSS-selector. The `elem` itself is also checked.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue