Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
quazimorda
5 лет назад
javascript

JavaScript 1. Ячейки таблицы меняют цвет при клике мышки


Давайте уже напишем простенький javascript-сценарий. Пока мы ещё не бросились во все тяжкие, так сказать – «на берегу», условимся о нескольких вещах. Во-первых, урок действительно будет простым, поэтому мы пока не будем использовать библиотек типа jQuery и стрелочных функций. Во-вторых, сейчас мне не важно, как именно выглядит веб-страница, где мы и поместим наш сценарий, то есть я совсем не желаю заморачиваться с оформлением текстов и таблички, которые, тем не менее, на странице будут. Это значит, что сейчас совсем не будет серверного языка PHP и почти не будет стилей CSS. В-третьих, хочется сделать упор на чистый JavaScript, но я не буду разбивать все составные части на отдельные файлы. Договоримся, что в этот раз весь код будет помещён в один файл index.html, а скрипт будет работать так: при первом нажатии на ячейку таблицы, этой ячейке будет присваиваться некий CSS-класс, а при повторном – сниматься. Класс опишем чуть позже, а пока пусть начальный вид странички будет таким, как указано ниже.

Листинг 1. Код без JavaScript
<!DOCTYPE html>
<html lang="ru">

<head>
    <meta charset="UTF-8">
    <title>Урок 1. Отрабатываем клик на ячейки таблицы</title>
</head>

<body>
    <h1>Отрабатываем клик на ячейки таблицы</h1>
    <table border="1" cellspacing="0" cellpadding="3">
        <thead>
            <tr>
                <th>Первая колонка</th>
                <th>Вторая</th>
                <th>Третья</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Что-нибудь напишем</td>
                <td>Текст второй ячейки</td>
                <td>И здесь пусть будет хоть какой-то текст</td>
            </tr>
        </tbody>
    </table>
</body>

</html>

Мы не можем наш сценарий разместить в заголовочной части head, так как собираемся обрабатывать события нажатий мышкой на ячейки таблицы с текстом. А самой таблицы, расположенной в блоке body, конечно в заголовочной части ещё не существует. Строго говоря, мы вообще всю таблицу из листинга 1 могли бы полностью создать в нашем сценарии, но так усложнять код в самом начале совсем не хочется.

Итак, инструкция «<!DOCTYPE html>» в самом начале файла указывает, что я использую HTML 5. Поэтому, в сценарии, который я размещу сразу после таблицы, я даже не стану писать, что это именно JavaScript-сценарий. Достаточно будет самого тега script без аргументов и атрибутов. И покамест я напишу только такие строки.

Листинг 2. Начинаем наш сценарий
<script>
    let tds = document.querySelectorAll('td');
    console.log(tds);
</script>

Поместите эти строки сразу после таблицы, сохраните файл и откройте его в браузере. Я воспользуюсь Мозиллой и сразу нажму F12, чтобы вызвать инструменты разработчика. Сайт отображается слева, инструменты разработчика – справа и мы по-умолчанию попадаем во вкладку «Инспектор».

В ней отображается содержимое нашего файла с некими дополнениями, но нас интересует вкладка «Консоль». Перейдите в неё. Что мы видим?

Давайте сначала разберём те пару строк, что сейчас есть в сценарии. В первой из них мы объявляем переменную, я назвал её tds, так как собираюсь в ней собрать ссылки на все объекты td – ячейки таблицы, чтобы позднее привязать к ним действие, которое будет происходить при нажатии на сами ячейки. Имя переменной я придумал как td и суффикс «s» от множественного числа из английского языка. Вольно имя этой переменной я бы перевёл как тэдэшки (от td – Table Dice). Старайтесь придумывать для переменных простые имена без зауми, но из которых было бы видно, что за значения в них хранятся. Так как ячеек в нашей таблице всего три (верхняя – заголовочная – строка таблицы не в счёт, так как там я использовал теги th), то в переменной будет собран узел Node, который как массив состоит из трёх объектов – ссылок на реальные ячейки таблицы. И как в обычном массиве эти элементы, а строго говоря, объекты нумеруются от нуля.

Вторая строка console.log(…) – важнейший инструмент для отслеживания работы наших JavaScript-сценариев. С его-то помощью мы и вывели собранные в переменной объекты в консоль. Щёлкая по треугольничками слева от элементов, мы можем увидеть довольно обширные списки свойств наших объектов, но сюда нам пока рано. Важно, что в переменной tds у нас имеется ссылка на узел документа, в котором собраны ссылки на три ячейки таблицы. Если бы необходимо было выбрать не все ячейки, а какую-то одну, пришлось бы возиться с классами или идентификаторами – всё это в будущем, но пока нам это не надо.

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

Итак, в переменной tds собран узел Node с ячейками таблицы td. У самого узла нет и не может быть события нажатия на него, а вот у ячеек таблицы – запросто. Поэтому теперь нам надо в цикле перебрать все собранные в переменную ячейки и к каждой из них привязать функцию с обработкой события с нажатием на ячейку. Код приобретает вид как в листинге 3.

Листинг 3. Обрабатываем ячейки в цикле
<script>
    let tds = document.querySelectorAll('td');
    //console.log(tds);
    tds.forEach(function(item)
    {
        console.log(item);
    });
</script>   

Легко убедиться в том, что теперь команда console.log(…), запущеная в цикле, обрабатывает и выводит в консоль конкретные ячейки таблицы, а не весь узел – Node. Значит, нам осталось отработать событие нажатия на ту или иную ячейку. Коротко говоря, мы воспользовались циклом forEach и перебрали все элементы из переменной tds. Если бы строка нашей таблицы состояла не из трёх ячеек, всё равно и в переменную tds были бы помещены они все, и цикл по отдельности обработал бы каждую из них. В цикле к любой конкретной ячейке мы обращаемся по имени переменной item (переводится как вещь или предмет, в нашем случае – отдельная ячейка). То есть tds – список (массив) всех ячеек, а item – каждая конкретная ячейка на любом шаге цикла.

«Приберёмся» в коде, удалим выводы в консоль и допишем наш код. Окончательный вариант скрипта и всего файла в целом примет вид как в листинге 4.

Листинг 4. Финальный вариант
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Урок 1. Отрабатываем клик на ячейки таблицы</title>
    <style>
        .greeny { background-color: #98FB98; }
    </style>
</head>

<body>
    <h1>Отрабатываем клик на ячейки таблицы</h1>
    <table border="1" cellspacing="0" cellpadding="3">
        <thead>
            <tr>
                <th>Первая колонка</th>
                <th>Вторая</th>
                <th>Третья</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Что-нибудь напишем</td>
                <td>Текст второй ячейки</td>
                <td>И здесь пусть будет хоть какой-то текст</td>
            </tr>
        </tbody>
    </table>
    <script>
        let tds = document.querySelectorAll('td');
        tds.forEach(function(item)
        {
            item.onclick = function()
            {
                this.classList.toggle('greeny');
            };
        });
    </script>
</body>

</html>

Давайте разберём код. В заголовочной части head я поместил описание стилей для класса «greeny» - в нём указывается цвет фона как светло-зелёный. Если применить его к любому элементу на странице, то фоновый цвет этого элемента поменяется, что и позволит нам убедиться, что наш скрипт работает для ячеек таблицы.

Оператор document.querySelectorAll('td'); перебирает все элементы документа и отбирает из них все селекторы, совпадающие с перечисленными в скобках. В нашем случае это td – ячейки таблицы.

В цикле forEach мы перебираем все элементы, включённые в узел Node на предыдущем шаге и к каждому из них обращаемся через переменную item.

Конструкция item.onclick = function() {… } объявляет функцию для события onClick (нажатие на item). Так как сделано это в цикле, то и отработает это для каждого элемента из цикла. Чуть позже я научу вас более правильно с точки зрения семантики привязывать обработчики событий к элементам DOM через addEventListener, а пока пойдёт и так.

Ну и, наконец, this.classList.toggle('greeny'); следует разобрать подробнее. Собственно, мы ещё будем и очень подробно касаться всего, о чём я говорю в этой заметке. Я сомневаюсь, а с того ли я начал? Всё-таки обычно в обучении идут от простого – к сложному. Начинают с определений, так сказать, с азов. С другой стороны, хотелось дать пример реального использования возможностей языка. В общем, я ещё буду думать, а пока разберём оператор. This – встроенный в JavaScript идентификатор, который в разных местах сценария ссылается на самые разные объекты. Это зависит от их области видимости и прочего.

В нашем случае через this мы обращаемся к конкретному td из собранных в узел. К тому самому, нажатие на который и привело к событию onClick. Точнее, this – это и есть та самая ячейка таблицы, именно у которой только что произошло событие нажатия на неё мышью. Далее, элементам DOM могут присваиваться те или иные классы и в classList находится список имён тех классов, которые элементу уже присвоены. К этому списку можно применять метод add – добавление имени класса к уже имеющимся, remove – удаление имени класса из списка, но мы воспользовались методом toggle – переключение. Он работает вполне предсказуемо: если в списке классов данного имени ещё нет – добавляет его, а если оно имелось – удаляет из списка.

Сохраните ваш файл, обновите его в браузере и убедитесь в том, что всё работает: собственно на странице меняется цвет фона у нажатых ячеек (включается или выключается при повторном нажатии), в Инспекторе можно видеть как к ячейкам таблицы то добавляется, то убирается класс «greeny», а в Консоли увидеть, что в нашем скрипте нет ошибок.

javascriptвебпрограммирование
1872
684.175 GOLOS
На Golos с May 2019
Комментарии (15)
Сортировать по:
Сначала старые