Используем dom как pro

Выбираем элементы в DOM-дереве с помощью parent(), next() и prev()

Если вы хотите пройтись по DOM-дереву для выборки родственных или родительских элементов, относительно какого-либо элемента, то вы можете это сделать с помощью методов , и . Которые вам нужно применить на интересующем вас элементе:

// jQuery// Отдаст следующий, предыдущий и родительский элемент для .box$(".box").next();$(".box").prev();$(".box").parent();// Без jQuery// Отдаст следующий, предыдущий и родительский элемент для .boxvar box = document.querySelector(".box");box.nextElementSibling;box.previousElementSibling;box.parentElement;

Работа с событиями

В jQuery есть огромное множество способов для того, чтобы слушать события, вместо , , или , вы могли бы сделать всё тоже самое с помощью их эквивалента :

// С jQuery$(".button").click(function(e) { /* handle click event */ });$(".button").mouseenter(function(e) {  /* handle click event */ });$(document).keyup(function(e) {  /* handle key up event */  });// Без jQuerydocument.querySelector(".button").addEventListener("click", (e) => { /* ... */ });document.querySelector(".button").addEventListener("mouseenter", (e) => { /* ... */ });document.addEventListener("keyup", (e) => { /* ... */ });

Определение и применение

JavaScript метод querySelector() объекта Element возвращает первый элемент, соответствующий указанной группе селекторов, который является потомком элемента на котором был вызван метод. Если совпадений не найдено, то возвращается значение null.

Этот метод так же реализован как Document.querySelector(), DocumentFragment.querySelector() и ParentNode.querySelector().

Обращаю Ваше внимание на то, что не допускается использование CSS псевдоэлементов в качестве значения селектора для поиска элементов, в этом случае в качестве возвращаемого значения всегда будет значение null. Если вам необходим первый элемент в документе, который соответствует указанному селектору или селекторам, то используйте для этого метод querySelector() объекта Document

Если вам необходим первый элемент в документе, который соответствует указанному селектору или селекторам, то используйте для этого метод querySelector() объекта Document.

Для того, чтобы возвратить статический (не живой) объект NodeList, представляющий список элементов, соответствующих указанной группе селекторов, которые являются потомками элемента на котором был вызван метод, Вы можете воспользоваться методом querySelectorAll().

Отладка JavaScript-кода

В примере ниже показан очень простой JavaScript-сценарий, добавленный в новый тег <script> на предыдущей странице:

В этом коде мы не использовали возможностей библиотеки jQuery, а написали скрипты на чистом JavaScript (сравните объем этого кода с примером чуть ниже, где реализуется тот же функционал, но используется библиотека jQuery).

Обратите внимание, что этот простой сценарий содержит вывод вспомогательного сообщения на консоль (console.log). Консоль — это простое (но весьма полезное) средство, предоставляемое браузером и предназначенное для отображения отладочной информации, генерируемой сценарием в процессе выполнения

Вызов консоли осуществляется в разных браузерах по-разному. В Google Chrome для этого следует нажать комбинацию клавиш Ctrl + Shift + I и выбрать вкладку Console:

Как нетрудно заметить, результат, генерируемый вызовом метода console.log(), отображается в окне консоли вместе с дополнительной информацией о местонахождении источника сообщения (в данном случае это строки 34 и 42 файла test.html).

Значения параметров

Параметр Описание
selectors Аргумент должен соответствовать допустимой строке селектора, содержащей один или несколько селекторов. При указании нескольких селекторов необходимо разделять значения запятыми. В этом случае будет выбран первый найденный элемент из заданных селекторов. Если по какой-то причине вы используете в наименовании селекторов символы, которые не являются частью стандартного синтаксиса CSS, то при поиске такие символы должны быть экранированы с помощью символа обратной косой черты («\»). Поскольку обратная косая черта также является специальным символом (escape) в JavaScript, то при вводе литеральной строки ее необходимо экранировать дважды. Обязательный параметр.

Классы DOM-узлов

У разных DOM-узлов могут быть разные свойства. Например, у узла, соответствующего тегу , есть свойства, связанные со ссылками, а у соответствующего тегу – свойства, связанные с полем ввода и т.д. Текстовые узлы отличаются от узлов-элементов. Но у них есть общие свойства и методы, потому что все классы DOM-узлов образуют единую иерархию.

Каждый DOM-узел принадлежит соответствующему встроенному классу.

Корнем иерархии является , от него наследует и остальные DOM-узлы.

На рисунке ниже изображены основные классы:

Существуют следующие классы:

  • – это корневой «абстрактный» класс. Объекты этого класса никогда не создаются. Он служит основой, благодаря которой все DOM-узлы поддерживают так называемые «события», о которых мы поговорим позже.
  • – также является «абстрактным» классом, и служит основой для DOM-узлов. Он обеспечивает базовую функциональность: , , и т.д. (это геттеры). Объекты класса никогда не создаются. Но есть определённые классы узлов, которые наследуют от него: – для текстовых узлов, – для узлов-элементов и более экзотический – для узлов-комментариев.
  • – это базовый класс для DOM-элементов. Он обеспечивает навигацию на уровне элементов: , и методы поиска: , . Браузер поддерживает не только HTML, но также XML и SVG. Класс Element служит базой для следующих классов: , и .
  • – является базовым классом для всех остальных HTML-элементов. От него наследуют конкретные элементы:
    • – класс для тега ,
    • – класс для тега ,
    • – класс для тега ,
    • …и т.д, каждому тегу соответствует свой класс, который предоставляет определённые свойства и методы.

Таким образом, полный набор свойств и методов данного узла собирается в результате наследования.

Рассмотрим DOM-объект для тега . Он принадлежит классу .

Он получает свойства и методы из (в порядке наследования):

  • – этот класс предоставляет специфичные для элементов формы свойства,
  • – предоставляет общие для HTML-элементов методы (и геттеры/сеттеры),
  • – предоставляет типовые методы элемента,
  • – предоставляет общие свойства DOM-узлов,
  • – обеспечивает поддержку событий (поговорим о них дальше),
  • …и, наконец, он наследует от , поэтому доступны также методы «обычного объекта», такие как .

Для того, чтобы узнать имя класса DOM-узла, вспомним, что обычно у объекта есть свойство . Оно ссылается на конструктор класса, и в свойстве содержится его имя:

…Или мы можем просто привести его к :

Проверить наследование можно также при помощи :

Как видно, DOM-узлы – это обычные JavaScript объекты. Для наследования они используют классы, основанные на прототипах.

В этом легко убедиться, если вывести в консоли браузера любой элемент через . Или даже напрямую обратиться к методам, которые хранятся в , и т.д.

и

Большинство браузеров поддерживают в инструментах разработчика две команды: и . Они выводят свои аргументы в консоль. Для JavaScript-объектов эти команды обычно выводят одно и то же.

Но для DOM-элементов они работают по-разному:

  • выводит элемент в виде DOM-дерева.
  • выводит элемент в виде DOM-объекта, что удобно для анализа его свойств.

Попробуйте сами на .

Спецификация IDL

В спецификации для описания классов DOM используется не JavaScript, а специальный язык Interface description language (IDL), с которым достаточно легко разобраться.

В IDL все свойства представлены с указанием их типов. Например, , и т.д.

Небольшой отрывок IDL с комментариями:

Вызываем и создаем события

Вы можете вручную вызывать события с помощью в jQuery, а также в чистом JS при помощи . Метод может быть вызван совершенно на любом элементе и берёт , как первый аргумент:

// C jQuery// Вызываем myEvent на документе и .box$(document).trigger("myEvent");$(".box").trigger("myEvent");// Без jQuery// Создаем и запускаем myEventdocument.dispatchEvent(new Event("myEvent"));document.querySelector(".box").dispatchEvent(new Event("myEvent"));

Стилизация элементов

Если вы вызываете на элементе, чтобы поменять его CSS инлайново с помощью jQuery, то этого же эффекта вы можете добиться с помощью в чистом JavaScript.

// С jQuery// Выбирает .box и меняет его цвет текста на #000$(".box").css("color", "#000");// Без jQuery// Выбирает первый .box и меняет его цвет текста на #000document.querySelector(".box").style.color = "#000";

С jQuery вы можете передать объект с парами ключ-значения, чтобы стилизовать уже большое количество свойств за раз. В JavaScript вы можете выставить только одно значение за раз или указать вcе стили одной строкой:

// С jQuery// Передаем несколько стилей$(".box").css({  "color": "#000",  "background-color": "red"});// Без jQuery// Выставляем цвет на #000 и делаем фон краснымvar box = document.querySelector(".box");box.style.color = "#000";box.style.backgroundColor = "red";// Выставляем все стили разом, но перезаписываем уже существующиеbox.style.cssText = "color: #000; background-color: red";

elem.querySelector(query), elem.querySelectorAll(query)

Чтобы найти элементы, удовлетворяющие поисковому запросу, браузер не использует никаких сложных структур данных.

Он просто перебирает все подэлементы внутри элемента (или по всему документу, если вызов в контексте документа) и проверяет каждый элемент на соответствие запросу .

Вызов прекращает перебор после первого же найденного элемента, а собирает найденные элементы в «псевдомассив»: внутреннюю структуру данных, по сути аналогичную массиву JavaScript.

Этот перебор происходит очень быстро, так как осуществляется непосредственно движком браузера, а не JavaScript-кодом.

Оптимизации:

  • В случае поиска по ID: , большинство браузеров оптимизируют поиск, используя вызов .
  • Последние результаты поиска сохраняются в кеше. Но это до тех пор, пока документ как-нибудь не изменится.

getElementsByClassName

Возвращает группу элементов (поэтому и Elements), в которых присутствует искомый класс. Отличительная особенность от предыдущего метода — дозволено указать элемент, относительно которого начинать поиск. Это может быть и documentвыбирать элементы на всей странице, либо указатель на определённый блок. Например, получим все элементы с классом .da внутри контейнера #go.

После выполнения кода в массиве elems будут содержаться 3 элемента: .one, .two и .three.

Если же требуется получить всё на странице, достаточно сделать так:

К трём элементам выше добавится ещё один — #go (как видно из кода, ему тоже присвоен класс .da).

К сожалению, данный метод не поддерживается в Internet Explorer версии 8 и ниже. Это значит, что все обладатели Windows XP оказываются в пролёте. Можно сделать свою реализацию функции, которая оббежит все теги на странице и отберёт лишь те, className которых соответствует условию, но есть более удобные методы для работы.

document.getElementById или просто id

Если у элемента есть атрибут , то мы можем получить его вызовом , где бы он ни находился.

Например:

Также есть глобальная переменная с именем, указанным в :

…Но это только если мы не объявили в JavaScript переменную с таким же именем, иначе она будет иметь приоритет:

Пожалуйста, не используйте такие глобальные переменные для доступа к элементам

Это поведение соответствует , но поддерживается в основном для совместимости, как осколок далёкого прошлого.

Браузер пытается помочь нам, смешивая пространства имён JS и DOM. Это удобно для простых скриптов, которые находятся прямо в HTML, но, вообще говоря, не очень хорошо. Возможны конфликты имён. Кроме того, при чтении JS-кода, не видя HTML, непонятно, откуда берётся переменная.

В этом учебнике мы будем обращаться к элементам по в примерах для краткости, когда очевидно, откуда берётся элемент.

В реальной жизни лучше использовать .

Значение должно быть уникальным

Значение должно быть уникальным. В документе может быть только один элемент с данным .

Если в документе есть несколько элементов с одинаковым значением , то поведение методов поиска непредсказуемо. Браузер может вернуть любой из них случайным образом. Поэтому, пожалуйста, придерживайтесь правила сохранения уникальности .

Только , а не

Метод можно вызвать только для объекта . Он осуществляет поиск по по всему документу.

Перемещение элементов

Метод insertAdjacentElement также можно использовать для перемещения по существующим элементам в том же документе. Когда элемент, вставленный с помощью insertAdjacentElement, уже является частью документа, он будет просто перемещен.

Если у вас есть этот HTML:

<div class="first">
  <h1>Title</h1>
</div><div class="second">
  <h2>Subtitle</h2>
</div>

и допустим нем необходимо  вставить после :

const h1 = document.querySelector('h1');
const h2 = document.querySelector('h2');
h1.insertAdjacentElement('afterend', h2);

он будет просто перемещен, а не скопирован:

<div class="first">
  <h1>Title</h1>
  <h2>Subtitle</h2>
</div><div class="second">
  
</div>

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Добавление новых элементов

Код для добавления одного или нескольких элементов в дерево DOM печально известен быстрым ростом количеством требуемых строк. Допустим, вы хотите добавить следующую ссылку на свою страницу:

<a href="/home" class="active">Home</a>

Вам нужно будет сделать:

const link = document.createElement('a');
link.setAttribute('href', '/home');
link.className = 'active';
link.textContent = 'Home';document.body.appendChild(link);

Теперь представьте, что нужно сделать это для 10 элементов …

По крайней мере, jQuery позволяет вам сделать это намного быстрее:

$('body').append('<a href="/home" class="active">Home</a>');

Ну догадайся что? Есть нативный эквивалент insertAdjacentHTML:

document.body.insertAdjacentHTML('beforeend', 
'<a href="/home" class="active">Home</a>');

Метод insertAdjacentHTML позволяет вставить произвольную допустимую строку HTML в DOM в четырех позициях, указанных первым параметром:

  • : перед элементом
  • : внутри элемента до его первого потомка
  • : внутри элемента после его последнего потомка
  • : после элемента
<!-- beforebegin -->
<p>
  <!-- afterbegin -->
  foo
  <!-- beforeend -->
</p>
<!-- afterend -->

Это также значительно упрощает указание точной точки, где новый элемент должен быть вставлен. Скажем, вы хотите вставить <a> прямо перед этим <p>. Без insertAdjacentHTML вы бы сделали это:

const link = document.createElement('a');
const p = document.querySelector('p');
p.parentNode.insertBefore(link, p);

Теперь вы можете просто сделать:

const p = document.querySelector('p');
p.insertAdjacentHTML('beforebegin', '<a></a>');

Существует также эквивалентный метод для вставки элементов DOM:

const link = document.createElement('a');
const p = document.querySelector('p');
p.insertAdjacentElement('beforebegin', link);

и текста:

p.insertAdjacentText('afterbegin', 'foo');

More Examples

Example

Get all <p> elements inside a <div> element, and set the background color of the
first <p> element (index 0):

// Get the element with id=»myDIV» (a div), then get all p elements inside divvar x = document.getElementById(«myDIV»).querySelectorAll(«p»); 
// Set the background color of the first <p> element (index 0) in div
x.style.backgroundColor = «red»;  

Example

Get all <p> elements in a <div> with class=»example», and set the background of the
first <p> element:

// Get the element with id=»myDIV» (a div), then get all p elements with class=»example» inside divvar x = document.getElementById(«myDIV»).querySelectorAll(«p.example»); 
// Set the background color of the first <p> element with class=»example» (index 0) in div
x.style.backgroundColor = «red»;  

Example

Find out how many elements with class=»example» there are in a
<div> element (using the length
property of the NodeList object):

/* Get the element with id=»myDIV» (a div), then get all p elements with class=»example» inside div, and return the number of elements found */var x = document.getElementById(«myDIV»).querySelectorAll(«.example»).length; 

Example

Set the background color of all elements with class=»example» in a <div>
element:

// Get the element with id=»myDIV» (a div), then get all elements with class=»example» inside divvar x = document.getElementById(«myDIV»).querySelectorAll(«.example»);// Create a for loop and set the background color of all elements with class=»example» in divvar i;for (i = 0; i < x.length; i++) {  x.style.backgroundColor = «red»;}

Example

Set the background color of all <p> elements in a <div>
element:

// Get the element with id=»myDIV» (a div), then get all p elements inside divvar x = document.getElementById(«myDIV»).querySelectorAll(«p»);// Create a for loop and set the background color of all p elements in divvar i;for (i = 0; i < x.length; i++) {
  x.style.backgroundColor = «red»;}

Example

Set the border style of all <a> elements in a <div> element that have a «target»
attribute:

// Get the element with id=»myDIV» (a div), then get all <a> elements with a «target» attribute inside divvar x = document.getElementById(«myDIV»).querySelectorAll(«a»);// Create a for loop and set the border of all <a> elements with a target attribute in divvar i;for (i = 0; i < x.length; i++) {  x.style.border = «10px solid red»;}

Example

Set the background color of all <h2>, <div> and <span> elements in
a <div> element:

// Get the element with id=»myDIV» (a div), then get all <h2>, <div> and <span> elements inside <div>var x = document.getElementById(«myDIV»).querySelectorAll(«h2, div, span»);// Create a for loop and set the background color of all <h2>, <div> and <span> elements in <div>var i;for (i = 0; i < x.length; i++) {  x.style.backgroundColor = «red»;}

Что же это такое?

Наверняка, Вы знакомы с jQuery. И наверняка знаете про функцию , возвращающую элементы, соответствующие css-селектору (в ранних версиях можно было еще использовать XPath, но потом от него отказались).

Так вот, делает то же самое, но нативными средствами браузера.

Этот метод есть у всех элементов и документа. В случае, если метод вызывается у элемента, поиск по селетору производится среди всех элементов, вложенных в него.

Тектовые ноды, комментарии, CDATA-секции выбрать этим методом нельзя, только элементы.

Поддерживается всеми современными браузерами, Internet Explorer — начиная с версии 8.

Так вот, почти то же самое, что и , но возвращает только один (первый попавшийся) элемент, либо Null.

getElementsBy*

There are also other methods to look for nodes by a tag, class, etc.

Today, they are mostly history, as is more powerful and shorter to write.

So here we cover them mainly for completeness, while you can still find them in the old scripts.

  • looks for elements with the given tag and returns the collection of them. The parameter can also be a star for “any tags”.
  • returns elements that have the given CSS class.
  • returns elements with the given attribute, document-wide. Very rarely used.

For instance:

Let’s find all tags inside the table:

Don’t forget the letter!

Novice developers sometimes forget the letter . That is, they try to call instead of .

The letter is absent in , because it returns a single element. But returns a collection of elements, so there’s inside.

It returns a collection, not an element!

Another widespread novice mistake is to write:

That won’t work, because it takes a collection of inputs and assigns the value to it rather than to elements inside it.

We should either iterate over the collection or get an element by its index, and then assign, like this:

Looking for elements:

4 – $(‘ul’).on(‘click’, ‘a’, fn);

Данный пример немного отличается. Код jQuery используется для делегирования события. Обработчик используется для всех неупорядоченных списков. Но возвратная функция будет запускаться только целью (где пользователь нажимает кнопку) является ссылка.

Модерн

document.addEventListener('click', function(e) {
   if ( e.target.matchesSelector('ul a') ) {
      // Обработка
   }
}, false);

Технически, данный метод JavaScript не является полным соответствием примеру jQuery. Он привязывает обработчик события непосредственно к . А затем используется метод для определения того факта,  что цель (узел, на котором произошло нажатие кнопки) соответствует указанному селектору. Таким образом, мы привязываем единственный обработчик события.

Обратите внимание, что на момент написания урока все браузеры реализовывали с использованием префиксов: , , и так далее. Для нормализации метода, вы можете написать:

var matches;
 
(function(doc) {
   matches =
      doc.matchesSelector ||
      doc.webkitMatchesSelector ||
      doc.mozMatchesSelector ||
      doc.oMatchesSelector ||
      doc.msMatchesSelector;
})(document.documentElement);
 
document.addEventListener('click', function(e) {
   if ( matches.call( e.target, 'ul a') ) {
      // Обработка
   }
}, false);

Наследие

var uls = document.getElementsByTagName('ul');
 
addEvent(uls, 'click', function() {
   var target = e.target || e.srcElement;
   if ( target && target.nodeName === 'A' ) {
      // Обработка
   }
});

Для обеспечения обратной совместимости мы проверяем, что свойство (имя целевого элемента) равно нашему запросу

Обратите внимание на факт, что старые версии Internet Explorer иногда играют своими собственными правилами. Вы не захотите получать доступ к цели непосредственно из объекта 

Зазочется использовать .

Пример использования

<!DOCTYPE html>
<html>
	<head>
		<title>Использование JavaScript метода .querySelector() объекта Element</title>
	</head>
	<body>
		<button onclick = "myFunc()">Click me</button> <!-- добавляем атрибут событий onclick -->
		<div>
		        <ul>
		                <li>1</li>
		                <li>2</li>
		                <li>3</li>
		        </ul>
		</div>
		<script>
	function myFunc() {
	  const myDiv = document.body.querySelector( "div" ), // выбираем первый элемент <div> внутри элемента <body>
	        firstLi = myDiv.querySelector( "li" ); // выбираем первый элемент <li> внутри элемента <div>

	  firstLi.style.color = "orangered"; // устанавливаем элементу цвет текста		 
	}
		</script>
	</body>
</html>

В этом примере с использованием атрибута событий onclick при нажатии на кнопку (HTML элемент <button>) вызываем функцию myFunc(), которая с использованием JavaScript метода querySelector() выбирает первый элемент <div> внутри элемента <body>, затем с помощью этого же метода осуществляет поиск внутри выбранного элемента <div>, и находит внутри него первый элемент <li>. После этого устанавливает ему определенный цвет текста.

Результат нашего примера:


Пример использования JavaScript метода .querySelector() объекта ElementJavaScript Element

Трюки

Итак, а с чем же его можно есть?

Если Вы осуществляете траверс по селектору без использования и других специфичных для jQ псевдоклассов, можно использовать

$(document.querySelectorAll("#myDiv p"))

вместо

$("#myDiv p")

На обертывание staticNodeList в объект jQuery, конечно, уйдет какое-то время, но, в целом, такой код выполнится быстрее.

При помощи qSA можно достаточно просто определить, наведен ли курсор на элемент.
Пример (Opera, Safari, Chrome):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
	<head>
		<title></title>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
		<style type="text/css">
			.samplediv {
				border: dashed red 1px;
				margin: 30px;
			}
			.samplediv #hovered {display: none}
			.samplediv:hover #hovered {display: inline}
			.samplediv:hover #nothovered {display: none}
		</style>
	</head>
	<body>
		<div class="samplediv" id="test">
			<p>Javascript: <span id="status">I am not hovered</span></p>
			<p>Css: <span id="nothovered">I am not hovered</span><span id="hovered">I am hovered</span></p>
		</div>
		<script type="text/javascript">
			function isHovered(o){return (o.parentNode && o.parentNode.querySelector(":hover") == o);}
			
			document.getElementById("test").addEventListener('mouseover', function(){
				if (isHovered(this)) document.getElementById("status").innerHTML = "I am hovered";
			}, false);
			document.getElementById("test").addEventListener('mouseout', function(){
				if (!isHovered(this)) document.getElementById("status").innerHTML = "I am not hovered";
			}, false);
		</script>
	</body>
</html>

В Firefox 3.6 статус так и останется залипшим на «hovered». Это связано с тем, что в этом замечательном браузере на момент css-стиль еще не обновился. При этом на работает отлично. Т.е, выходит, что Firefox обновляет css между и . По-моему, это нелогично и неправильно. Разработчики Firefox, поправьте это, пожалуйста!

Но вернемся к функции . Работает она на одном достаточно простом предположении: если у родителя элемента есть элементы, на которые наведен курсор, и один из этих элементов (нулевой в массиве, траверс начинается с непсредственных детей) — сам исходный элемент, то на исходный элемент наведен курсор.

У родитель — , соответственно, код тоже работает. У же родителя нет, но и hover для него бессмысленнен.

Как Вы уже, наверное, догадались, таким же нехитрым способом можно определить, а какой же инпут имеет фокус сразу при загрузке страницы.

document.querySelector(":focus")

Определение и применение

JavaScript метод document.querySelectorAll() возвращает список элементов в пределах документа (статичный (не живой) объект типа NodeList), соответствующих указанному селектору, или группе селекторов. Если совпадений не найдено, то возвращается пустой объект типа NodeList.

Объект NodeList представляет из себя набор узлов, к котрым можно обращаться по номерам индексов, индекс коллекции начинается с 0. Вы можете использовать свойство length объекта NodeList для определения количества элементов, соответствующих указанному селектору и при необходимости перебирать все эти элементы в цикле.

Обращаю Ваше внимание на то, что не допускается использование CSS псевдоэлементов в качестве значения селектора для поиска элементов, в этом случае в качестве возвращаемого значения всегда будет пустое значение. Если вам необходим первый элемент в документе (объект Element), соответствующий указанному селектору, или группе селекторов, то используйте для этого метод querySelector()

Если вам необходим первый элемент в документе (объект Element), соответствующий указанному селектору, или группе селекторов, то используйте для этого метод querySelector().

Метод .querySelectorAll() также определен в объекте Element, по этой причине он может быть вызван на любом элементе, не только на объекте document. Элемент на котором он вызывается будет использован в качестве корневого элемента для поиска.

nodeValue/data: содержимое текстового узла

Свойство есть только у узлов-элементов.

У других типов узлов, в частности, у текстовых, есть свои аналоги: свойства и . Эти свойства очень похожи при использовании, есть лишь небольшие различия в спецификации. Мы будем использовать , потому что оно короче.

Прочитаем содержимое текстового узла и комментария:

Мы можем представить, для чего нам может понадобиться читать или изменять текстовый узел, но комментарии?

Иногда их используют для вставки информации и инструкций шаблонизатора в HTML, как в примере ниже:

…Затем JavaScript может прочитать это из свойства и обработать инструкции.

Другие свойства

У DOM-элементов есть дополнительные свойства, в частности, зависящие от класса:

  • – значение для , и (, …).
  • – адрес ссылки «href» для ().
  • – значение атрибута «id» для всех элементов ().
  • …и многие другие…

Например:

Большинство стандартных HTML-атрибутов имеют соответствующее DOM-свойство, и мы можем получить к нему доступ.

Если мы хотим узнать полный список поддерживаемых свойств для данного класса, можно найти их в спецификации. Например, класс описывается здесь: .

Если же нам нужно быстро что-либо узнать или нас интересует специфика определённого браузера – мы всегда можем вывести элемент в консоль, используя , и прочитать все свойства. Или исследовать «свойства DOM» во вкладке Elements браузерных инструментов разработчика.

10 – $()

Определенно, цель полностью заменить jQuery API выходит за рамки данного урока. Но часто в проектах функции или используются для короткой записи получения одного или нескольких элементов из DOM.

Модерн

var $ = function(el) {
   return document.querySelectorAll(el);
};
// Использование = $('.box');

Это просто односимвольный указатель на . Сохраняет время!

Наследие

if ( !document.getElementsByClassName ) {
   document.getElementsByClassName = function(cl, tag) {
      var els, matches = [],
         i = 0, len,
         regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
     
      // Если не задано имен тегов,
      // мы будем получать все элементы из DOM    
      els = document.getElementsByTagName(tag || "*");
      if ( !els ) return false;
 
      for ( len = els.length; i < len; i++ ) {
         if ( els.className.match(regex) ) {
            matches.push( els);
         }
      }
      return matches; // массив элементов, которые имеют определённое имя класса
   };
}
  
// Очень простая реализация. Проверяем id, класс и имя тега.
var $ = function(el, tag) {
   var firstChar = el.charAt(0);
  
   if ( document.querySelectorAll ) return document.querySelectorAll(el);
  
   switch ( firstChar ) {
      case "#":
         return document.getElementById( el.slice(1) );
      case ".":
         return document.getElementsByClassName( el.slice(1), tag );
      default:
         return document.getElementsByTagName(el);
   }
};
 
// Использование
$('#container');
$('.box'); // Любые элементы с классом box
$('.box', 'div'); // Элементы div с классом box
$('p'); // Получаем все элементы p

К сожалению, метод обратной достаточно большой. В данном случае лучше использовать библиотеку. jQuery оптимизирован для работы с DOM! Пример выше будет работать, но он не поддерживает сложные селекторы CSSв старых браузерах.

Пример использования

<!DOCTYPE html>
<html>
	<head>
		<title>Использование JavaScript метода document.querySelector()</title>
	</head>
	<body>
		<button onclick = "myFunc()">Нажми меня</button> <!-- добавляем атрибут событий onclick -->
		<div class = "block first">Первый блок</div>
		<div class = "block">Второй блок</div>
		<div class = "block">Третий блок</div>
		<script>
	function myFunc() {
	  let firstBlock = document.querySelector( ".block" ),   // выбираем элемент с классом block
	      first = document.querySelector( ".first, .block" ), // находим первый элемент из заданных селекторов
	      second = document.querySelector( "div:nth-of-type(2)" ), // выбираем каждый элемент div, который является вторым дочерним элементом своего родительского элемента
	      third = document.querySelector( "div:last-of-type" ); // находим каждый элемент div, который является последним из элементов своего родительского элемента

	  firstBlock.style.background = "black";    // изменяем цвет заднего фона у элемента
	  first.style.color = "red";    // изменяем цвет текста у элемента
	  second.style.color = "green"; // изменяем цвет текста у элемента
	  third.style.color = "blue";   // изменяем цвет текста у элемента		
	  	  }
		</script>
	</body>
</html>

В этом примере мы с использованием атрибута событий onclick при нажатии на кнопку (HTML элемент <button>) вызываем функцию myFunc(), которая с использованием JavaScript метода document.querySelector() выбирает следующие элементы:

  • Первый элемент с классом block в документа и устанавливаем черный цвет заднего фона найденному элементу.
  • Первый элемент из заданных селекторов (элемент с классом first, элемент с классом block) и устанавливаем красный цвет текста найденному элементу. В этом случае будет выбран первый найденный элемент из заданных селекторов.
  • Элемент <div>, который является вторым дочерним элементом своего родительского элемента и устанавливаем найденному элементу зеленый цвет текста.
  • Элемент <div>, который является последним из элементов своего родительского элемента и устанавливаем найденному элементу синий цвет текста.

Результат нашего примера:


Пример использования JavaScript метода document.querySelector()JavaScript Document

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
Добавить комментарий