DOM-элементы. События. Ввод.

JavaScript простым языком

Ты даже не представляешь, как много всего происходит в браузере, когда ты производишь какие-то действия: кликаешь ли мышкой, причём браузер различает, правой и/или левой мышью ты кликнул, отслеживает поведение колесика твоей мышки (представляешь?), отслеживает над каким элементом ты сейчас водишь мышкой и т.д и т.п.

Поэтому в этом уроке я хочу начать разбирать тему событий.

Создание странички

Давай разберем событие клика по кнопке. Создаем html-страницу, на которой будет текст и 2 кнопки:

Код этой страницы:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>repl.it</title>
    <link href="style.css" rel="stylesheet" type="text/css"/>
  </head>
  <body>
    <p id="text">Я текст, над которым издеваются</p>

    <button id="btnRed">Покрасить текст в красный</button>

    <button id="btnGreen">Покрасить текст в зеленый</button>

    <script src="script.js"></script>
  </body>
</html>

Итак, что мы здесь имеем? Мы имеем тэг p с id="text" и 2 кнопки: одна с id="btnRed", а другая с id="btnGreen". При нажатии на кнопку, текст в тэге p должен перекрашиваться в соответствующий цвет, который указан на кнопке.

Выбор нужных элементов

Что нам необходимо? Нам необходимо с помощью JavaScript получить 3 элемента для управления и обработки событий: тэг p, и 2 тэга button. Пишем в файле script.js свой JS-код:

let text = document.getElementById('text');
let btnRed = document.getElementById('btnRed');
let btnGreen = document.getElementById('btnGreen');

Так что мы сделали? Правильно, мы с помощью JavaScript нашли требуемые нам элементы и теперь можем с ними работать. А что произойдет, если ты не разместил элемент на странице или ошибся с указанием id? В значение переменной JavaScript запишет значение null. Поэтому будь внимательным.

Детектим событие click

Что нам необходимо сделать дальше? Дальше нам необходимо как-то объяснить браузеру, что мы хотим выполнить некоторые действия при нажатии на кнопки. Два самых популярных способа сделать это средствами JavaScript: использовать метод onclick у элемента button, либо использовать метод addEventListener.

Метод onclick

К коду:

btnRed.onclick = function() {
  text.style.color = 'red';
  alert('Цвет текста изменен на красный');
};

Сначала о том, что здесь происходит. Как только произойдет клик по кнопке с id="btnRed", выполнится код, находящийся внутри указанной функции, т.е.:

text.style.color = 'red';
alert('Цвет текста изменен на красный');

У элемента с id="text" поменяется цвет текста на красный и появится сообщение, которое сообщит об этом пользователю.

Метод onclick вызывается непосредственно у того элемента, событие которого мы хотим обрабатывать. В данном случае, мы обрабатываем событие клика у элемента btnRed. Синтаксис достаточно простой. Все, что нужно – это определить метод onclick, т.е. задать функцию, которая будет выполняться в том случае, если на элемент, в данном случае, кнопку btnRed кликнут мышкой (замечу, что onclick отработает только при клике по элементу левой кнопкой мыши).

В данном случае, мы указали стандартную функцию, но можно указать и стрелочную:

btnRed.onclick = () => {
  text.style.color = 'red';
  alert('Цвет текста изменен на красный');
};

Все будет работать точно так же. Какой вариант лучше? Т.к. я больше пользуюсь возможностями ES6, то и пишу я в таких случаях чаще всего стрелочную функцию, т.е. мой выбор – 2 вариант. Аналогично этому обработчику события ты должен создать еще один такой же обработчик, но для другой кнопки. По коду изменится только цвет, который ты хочешь выставить. Итого, файл script.js должен иметь примерно следующий вид:

let text = document.getElementById('text');
let btnRed = document.getElementById('btnRed');
let btnGreen = document.getElementById('btnGreen');

btnGreen.onclick = () => {
  text.style.color = 'green';
  alert('Цвет текста изменен на зеленый');
});

btnRed.addEventListener('click', () => {
  text.style.color = 'red';
  alert('Цвет текста изменен на красный');
});

Я намерено использовал разные методы для обработки события click, чтобы показать оба.

Метод addEventListener

Кроме метода onclick очень часто для обработки тех же кликов можно увидеть следующую конструкцию, которая работает ровно так же:

btnRed.addEventListener('click', () => {
  text.style.color = 'red';
  alert('Цвет текста изменен на красный');
});

Синтаксис также очень похож на предыдущий метод, за исключением того, что в onclick мы записываем конкретную функцию, которая вызовется при отработке события click, а здесь мы передаем внутрь метода 2 аргумента addEventListenner: название события, которое мы хотим слушать у элемента и функцию, которая выполнится, когда данное событие произойдет. Здесь также можно использовать стандартную функцию, описание которой начинается с ключевого слова function, либо, снова используем стрелочную функцию, как я и сделал в данном примере.

Разница между onclick и addEventListener

Разница на самом деле в том, что addEventListener более универсальный метод, который может принимать в качестве аргумента огромный список событий (посмотреть все события можно здесь). Т.е., этот метод общий для нескольких десятков событий.

Метод onclick – обрабатывает только клик по кнопке и больше ничего.

Хочу чтобы ты обратил внимание на то, что сокращенная запись событий есть не только у клика (onclick), но и практически у всех других событий, которые может отдавать элемент.

Улучшим наш код

Просто ради того, чтобы зацепить побольше пройденных тем, я хочу улучшить тот код, который у нас получился ранее.

Первое улучшение

Во-первых, обрати внимание на то, как ты получаешь элементы.

let text = document.getElementById('text');
let btnRed = document.getElementById('btnRed');
let btnGreen = document.getElementById('btnGreen');

Чем отличаются эти 3 строки? Правильно, только названием переменных и id, которые мы передаем в метод getElementById. Не кажется ли тебе, что эти строки слишком длинные для того чтобы их повторять? Давай улучшим это. Для этого добавим свою функцию getElement:

function getElement(idElement) {
  return document.getElementById(idElement);
}

Надеюсь, ты понимаешь, что делает эта функция. Если нет, я повторю: функция принимает как аргумент id элемента, который ты хочешь найти в документе и возвращает тебе значение, которое возвращает метод getElementById. Теперь наш переработанный код будет выглядеть так:

let text = getElement('text');
let btnRed = getElement('btnRed');
let btnGreen = getElement('btnGreen');

Как видишь, теперь запись стала короче, но, при этом смысл абсолютно не поменялся. Более того, если вдруг, ты решишь поменять поведение процесса выбора элемента, то тебе не нужно будет исправлять это во всем коде, а лишь поправить только в функции getElement и во всех остальных частях кода это автоматически применится. Круто, не правда ли?

Второе улучшение

Внутрь нашей функции getElement мы передаем id-элемента, который мы хотим получить. И передаем мы его явной строкой. Но давай подумаем, а удобно ли это? Представь, если у нас в коде будет не как сейчас 20 строк, а хотя бы 300-400, удобно ли будет искать название id во всем коде? Наверное нет. Поэтому у программистов есть негласное правиловсе строковые значения, которые никак не будут меняться походу написания программного кода нужно выносить в отдельные переменные, так называемые константы.

Константы представляют собой обычные переменные, которые инициализируются с помощью ключевого слова const(неудивительно, да?). Но есть одно отличие от обычных переменных в именовании константы. Ты должен назвать ее с помощью включенного CAPS LOCK =) Т.е., переменная должна иметь следующий вид:

const TEXT_ID = 'text';

И в разделении слов используется стиль не camelCase (когда одно слово заканчивается, а второе начинается с заглавной буквы), а стилем snake case(когда одно слово в названии переменной разделяется от другого нижним подчеркиванием).

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

const TEXT_ID = 'text';
const BTN_RED = 'btnRed';
const BTN_GREEN = 'btnGreen';
const RED_COLOR = 'red';
const GREEN_COLOR = 'green';
const TEXT_CHANGE_TO_GREEN = 'Цвет текста изменен на зеленый';
const TEXT_CHANGE_TO_RED = 'Цвет текста изменен на красный';

function getElement(idElement) {
  return document.getElementById(idElement);
}

let text = getElement(TEXT_ID);
let btnRed = getElement(BTN_RED);
let btnGreen = getElement(BTN_GREEN);

btnRed.onclick = function() {
  text.style.color = RED_COLOR; // тоже заменяем во всех\ 
  // методах на нужную константу
  alert(TEXT_CHANGE_TO_RED);
};

btnGreen.addEventListener('click', () => {
  text.style.color = GREEN_COLOR;
  alert(TEXT_CHANGE_TO_GREEN);
});

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

Третье улучшение

Пойдем еще дальше. Наверное ты заметил, что внутри каждого метода мы устанавливаем цвет текста такой строкой:

text.style.color = GREEN_COLOR;

Знаешь на что я намекаю? На то, что нужно создать еще одну функцию, которая будет принимать значение цвета и устанавливать его для элемента с id="text".

function setTextColor(color) {
  text.style.color = color;
}

Снова меняем наш код и получаем:

const TEXT_ID = 'text';
const BTN_RED = 'btnRed';
const BTN_GREEN = 'btnGreen';
const RED_COLOR = 'red';
const GREEN_COLOR = 'green';
const TEXT_CHANGE_TO_GREEN = 'Цвет текста изменен на зеленый';
const TEXT_CHANGE_TO_RED = 'Цвет текста изменен на красный';

function getElement(idElement) {
  return document.getElementById(idElement);
}

function setTextColor(color) {
  text.style.color = color;
}

let text = getElement(TEXT_ID);
let btnRed = getElement(BTN_RED);
let btnGreen = getElement(BTN_GREEN);

btnRed.onclick = function() {
  setTextColor(RED_COLOR); // тоже заменяем во всех \
  // методах на нужную константу
  alert(TEXT_CHANGE_TO_RED);
};

btnGreen.addEventListener('click', () => {
  setTextColor(GREEN_COLOR);
  alert(TEXT_CHANGE_TO_GREEN);
});

Теперь, когда мы вынесли изменение цвета в отдельную функцию, в случае изменения логики, изменения цвета мы также поменяем эту логику только внутри самой функции.

Домашнее задание

Даю ссылку на код.

Твоя задача:

  • полностью разобраться с тем, что там происходит;

  • добавить свою кнопку и обработать событие клика, которая будет перекрашивать текст в желтый.

Last updated