Урок 10: Итоговый проект и лучшие практики с jQuery

Наконец то мы подошли к финальному, десятому уроку нашего курса по jQuery для начинающих. Это настоящий рубеж. Сегодня мы не будем изучать новые методы, а соберем все полученные за девять уроков знания воедино.

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

Пишем простое одностраничное приложение

Давайте создадим что-то осязаемое. Простое, но функциональное одностраничное приложение «Менеджер задач». Цель будет не просто в том, чтобы добавить и удалить элемент из списка, а в том, чтобы имитировать работу с сервером, используя AJAX. Мы воспользуемся бесплатным тестовым API JSONPlaceholder, который позволяет нам имитировать создание, чтение и удаление данных.

Наше приложение будет уметь:

  • Показывать список задач (с сервера).

  • Добавлять новую задачу (отправляя POST-запрос).

  • Отмечать задачу как выполненную (чечеркивание текста).

  • Удалять задачу (отправляя DELETE-запрос).

Шаг 1: Базовая HTML-разметка

Создадим простой каркас для нашего приложения.

html
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Менеджер задач на jQuery</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 20px auto; }
        .completed { text-decoration: line-through; color: #888; }
        #task-list { list-style: none; padding: 0; }
        #task-list li { padding: 10px; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; }
        button { margin-left: 10px; cursor: pointer; }
        input[type="text"] { padding: 8px; width: 70%; }
    </style>
</head>
<body>
    <h1>Мой Менеджер Задач</h1>
    <div>
        <input type="text" id="new-task" placeholder="Введите новую задачу...">
        <button id="add-task">Добавить</button>
    </div>
    <ul id="task-list"></ul>

    <script>
        // Здесь будет наш JavaScript/jQuery код
    </script>
</body>
</html>

Шаг 2: Загружаем существующие задачи при загрузке страницы

Используем $.get() для получения списка задач с JSONPlaceholder.

javascript
$(document).ready(function() {
    // Функция для загрузки и отображения задач
    function loadTasks() {
        $.get('https://jsonplaceholder.typicode.com/todos?_limit=5', function(tasks) {
            $('#task-list').empty(); // Очищаем список перед добавлением
            tasks.forEach(function(task) {
                // Для каждой задачи создаем элемент списка
                const $li = $('<li></li>');
                $li.html(`<span>${task.title}</span>`);
                if (task.completed) {
                    $li.find('span').addClass('completed');
                }

                // Создаем кнопки для отметки и удаления
                const $completeBtn = $('<button>+</button>');
                const $deleteBtn = $('<button>-</button>');

                $li.append($completeBtn).append($deleteBtn);
                $('#task-list').append($li);
            });
        }).fail(function() {
            console.error("Ошибка при загрузке задач");
        });
    }

    // Вызываем функцию при старте
    loadTasks();
});

Шаг 3: Добавляем новую задачу

Теперь реализуем функционал добавления. Мы будем отправлять POST-запрос, а после успешного ответа сервера, добавлять задачу в список и очищать поле ввода.

javascript
$('#add-task').on('click', function() {
    const taskText = $('#new-task').val().trim();
    if (taskText === '') return; // Не добавляем пустые задачи

    // Отправляем POST-запрос
    $.post('https://jsonplaceholder.typicode.com/todos', {
        title: taskText,
        completed: false,
        userId: 1
    }, function(newTaskFromServer) {
        // JSONPlaceholder возвращает объект с id, который он бы присвоил
        // В реальном приложении мы бы использовали данные из ответа
        const $li = $('<li></li>');
        $li.html(`<span>${taskText}</span>`); // Используем наш текст, т.к. сервер его эхоит

        const $completeBtn = $('<button>+</button>');
        const $deleteBtn = $('<button>-</button>');

        $li.append($completeBtn).append($deleteBtn);
        $('#task-list').append($li);

        $('#new-task').val(''); // Очищаем поле ввода
    }).fail(function() {
        alert('Ошибка при добавлении задачи!');
    });
});

Шаг 4: Отмечаем задачу как выполненную и удаляем ее

Здесь важно использовать делегирование событий, так как наши кнопки динамически добавляются в DOM.

javascript
// Обработчик для отметки задачи (делегирование событий)
$('#task-list').on('click', 'button:contains("+")', function() {
    const $taskSpan = $(this).parent().find('span');
    $taskSpan.toggleClass('completed');

    // В реальном приложении здесь был бы PATCH-запрос на /todos/{id}
    // для обновления свойства 'completed'
    // $.ajax({ url: `https://jsonplaceholder.typicode.com/todos/1`, method: 'PATCH', data: {completed: true} })
});

// Обработчик для удаления задачи (делегирование событий)
$('#task-list').on('click', 'button:contains("-")', function() {
    const $li = $(this).parent();
    // Имитируем удаление с сервера. В реальности сначала запрос, потом удаление из DOM.
    $.ajax({
        url: 'https://jsonplaceholder.typicode.com/todos/1', // Здесь должен быть ID задачи
        method: 'DELETE'
    }).done(function() {
        // Если сервер ответил "OK", удаляем элемент из DOM
        $li.fadeOut(500, function() {
            $(this).remove();
        });
    }).fail(function() {
        alert('Ошибка при удалении задачи!');
    });
});

Практическая задача: Добавьте в этот менеджер задач возможность редактирования существующей задачи по двойному клику на ее тексте. Используйте метод .dblclick() и замените span на input для редактирования, отправляя затем PATCH-запрос на сервер.

Структурирование кода

Когда проект растет, а весь код написан в одной куче, как в примере выше, он быстро превращается в «спагетти-код». Запутанный, сложный для чтения и поддержки. Давайте разберем простые, но эффективные способы структурировать наш jQuery-код.

1. Используйте модульный подход с помощью объектов

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

javascript
const TaskManager = {
    // Свойства (данные приложения)
    apiUrl: 'https://jsonplaceholder.typicode.com/todos',
    $taskList: $('#task-list'),
    $newTaskInput: $('#new-task'),

    // Методы (функции приложения)
    init: function() {
        this.bindEvents();
        this.loadTasks();
    },

    bindEvents: function() {
        const self = this; // Сохраняем контекст
        $('#add-task').on('click', $.proxy(this.addTask, this));
        this.$taskList
            .on('click', 'button:contains("+")', $.proxy(this.toggleComplete, this))
            .on('click', 'button:contains("-")', $.proxy(this.deleteTask, this));
    },

    loadTasks: function() {
        const self = this;
        $.get(this.apiUrl + '?_limit=5', function(tasks) {
            self.$taskList.empty();
            tasks.forEach(self.renderTask.bind(self));
        });
    },

    renderTask: function(task) {
        const $li = $('<li></li>');
        const $span = $('<span></span>').text(task.title);
        if (task.completed) {
            $span.addClass('completed');
        }
        $li.append($span)
           .append($('<button>+</button>'))
           .append($('<button>-</button>'));
        this.$taskList.append($li);
    },

    addTask: function() {
        const self = this;
        const taskText = this.$newTaskInput.val().trim();
        if (!taskText) return;

        $.post(this.apiUrl, { title: taskText, completed: false }, function(newTask) {
            self.renderTask({ title: taskText, completed: false }); // Рендерим локально
            self.$newTaskInput.val('');
        });
    },

    toggleComplete: function(event) {
        const $taskSpan = $(event.target).parent().find('span');
        $taskSpan.toggleClass('completed');
        // ... AJAX запрос на обновление
    },

    deleteTask: function(event) {
        const $li = $(event.target).parent();
        const self = this;
        // Предположим, что id задачи хранится в data-атрибуте
        // const taskId = $li.data('id');
        $.ajax({
            // url: this.apiUrl + '/' + taskId,
            url: this.apiUrl + '/1',
            method: 'DELETE'
        }).done(function() {
            $li.fadeOut(500, function() { $(this).remove(); });
        });
    }
};

// Инициализируем приложение после загрузки DOM
$(document).ready(function() {
    TaskManager.init();
});

2. Разделяйте код по файлам

В реальном проекте вы можете разнести код по логическим файлам:

  • app.js основной файл с объектом TaskManager и инициализацией.

  • models/Task.js модель задачи (если бы она была сложнее).

  • views/TaskView.js логика отрисовки одной задачи.

Затем вы просто подключаете эти файлы в HTML в правильном порядке.

3. Используйте пространства имен

Если у вас несколько больших модулей на странице (например, TaskManagerUserProfileNewsFeed), создавайте их как отдельные объекты в глобальной области видимости, чтобы избежать конфликтов имен.

4. Комментируйте и давайте понятные имена

loadTasks() понятнее, чем lt(), а renderSingleTaskItem() яснее, чем rst(). Пишите комментарии для сложных кусков логики, но старайтесь писать код так, чтобы он был самодокументирующимся.

Когда jQuery использовать, а когда нет?

Зачем учить jQuery, когда есть React, Vue и Angular? Это отличный вопрос и ответ на него неоднозначен.

Когда jQuery все еще уместна и даже прекрасна?

  1. Небольшие проекты и сайты. Если вам нужно добавить на простой лендинг пару интерактивных элементов (слайдер, попап, плавную прокрутку), то поднимать React для этого все равно что стрелять из пушки по воробьям. jQuery сделает это быстро, просто и без лишней сложности в настройке сборки.

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

  3. Быстрое прототипирование. Нужно быстро «накидать» рабочую демку идеи? jQuery позволяет очень быстро создать интерактивный интерфейс, не заморачиваясь с состоянием, виртуальным DOM и прочими концепциями.

  4. Работа с DOM и анимации. Для простых манипуляций с DOM и анимаций синтаксис jQuery зачастую все еще более лаконичен и понятен, чем нативный JavaScript.

Когда стоит выбрать современный фреймворк?

  1. Сложные одностраничные приложения (SPA). Если ваше приложение имеет множество состояний, сложную маршрутизацию, требует высокой интерактивности и переиспользования компонентов React, Vue или Angular справятся с этим намного лучше. Они предоставляют строгую архитектуру, которая помогает управлять сложностью.

  2. Командная разработка. Фреймворки навязывают определенную структуру проекта и подход к коду, что облегчает работу большой команды.

  3. Производительность. Виртуальный DOM в React, к примеру, может быть более эффективным при частых и сложных обновлениях интерфейса, чем прямое манипулирование реальным DOM через jQuery.

  4. Экосистема. Современные фреймворки это целые экосистемы с инструментами для управления состоянием (Redux, Vuex), маршрутизации (React Router, Vue Router) и т.д.

jQuery это не «устаревший» инструмент, а инструмент для конкретных задач. Это надежный швейцарский армейский нож, который отлично лежит в руке для многих бытовых задач. Но для строительства небоскреба вам понадобится не нож, а целый арсенал специализированной техники. Изучив jQuery, вы отлично понимаете основы работы с DOM и событиями, что очень пригодится вам при изучении любых фреймворков.

Инструменты для отладки: Console и DevTools

Умение отлаживать код, это навык не менее важный, чем умение его писать. К счастью, современные браузеры дают нам инструмент, это Developer Tools (инструменты разработчика).

1. Консоль (Console)

Не ограничивайтесь использованием console.log() для вывода переменной. Есть много других полезных методов:

  • console.log('Простое сообщение:', myVariable); для общего вывода.

  • console.warn('Предупреждение!'); выводит желтое предупреждение.

  • console.error('Ошибка!'); выводит красное сообщение об ошибке.

  • console.table(arrayOfObjects); выводит массив объектов в виде удобной таблицы. Отлично подходит для просмотра данных, пришедших с сервера.

  • console.dir($('mySelector')); выводит свойства DOM-элемента в иерархическом виде.

  • console.group('Группа действий') и console.groupEnd() позволяют группировать сообщения.

javascript
// Пример в нашем менеджере задач
loadTasks: function() {
    const self = this;
    console.group('Загрузка задач с сервера');
    $.get(this.apiUrl + '?_limit=5', function(tasks) {
        console.log('Задачи успешно загружены:', tasks);
        console.table(tasks); // Выведет красивущую таблицу
        self.$taskList.empty();
        tasks.forEach(self.renderTask.bind(self));
        console.groupEnd();
    }).fail(function(jqXHR, textStatus, errorThrown) {
        console.error('Ошибка AJAX:', textStatus, errorThrown);
        console.groupEnd();
    });
}

2. Инструменты разработчика (F12)

  • Вкладка Elements (элементы). Позволяет просматривать и изменять DOM в реальном времени. Вы можете редактировать атрибуты, классы и стили, чтобы сразу видеть результат. Это незаменимо для отладки селекторов и визуальных эффектов.

  • Вкладка Sources (источники). Здесь можно ставить точки останова (breakpoints) в вашем JavaScript-коде. Когда выполнение кода дойдет до этой точки, оно остановится и вы сможете в реальном времени просматривать значения всех переменных, ходя по коду шаг за шагом. Это самый мощный способ найти логическую ошибку.

  • Вкладка Network (сеть). Показывает все сетевые запросы, которые делает ваша страница. Вы можете увидеть, ушел ли ваш AJAX-запрос, какой был URL, метод, статус ответа (200 – OK, 404 – Не найдено, 500 – Ошибка сервера) и что именно вернул сервер. Если ваш AJAX не работает, первым делом идите сюда!

Практическая задача: Откройте ваше приложение «Менеджер задач» в браузере, откройте DevTools (F12) и поставьте точку останова внутри обработчика клика для кнопки «Добавить». Посмотрите, чему равна переменная taskText в момент срабатывания. Затем перейдите на вкладку Network, добавьте новую задачу и найдите в списке POST-запрос, который ушел на JSONPlaceholder.

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

Практикуйтесь, читайте документацию (api.jquery.com) и смотрите, как устроен код популярных плагинов и постепенно начинайте знакомиться с современными фреймворками.

Ссылка на полный курс: курс с уроками по jQuery для начинающих.

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий