November 7, 2018

Часть вторая: собственно, фронтенд

Верстка будто бы завершена, следующий этап — вдохнуть в страницу жизнь и интерактивность.

Для этого нам понадобится JavaScript (для того, чтобы разобраться в основах — чистый). Как и CSS, его можно вставлять прямо в html-код, используя тэг <script></script>, но более грамотным будет подключить внешний файл.

Добавим в <head> ссылку на скрипт:

<script src="myscripts.js"></script>

Наша первоочередная задача — научиться добавлять элементы (узлы) на веб-страницу.

Элементы добавляются к уже существующим элементам. Для того, чтобы к ним обращаться, мы будем работать с DOM-деревом.

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

Мы сделаем первое, чтобы не трогать уже существующий css,и добавим к контейнеру сообщений id = "messages-container", а к полю ввода — id = "message-input"

<head>
    <link rel="stylesheet" type="text/css" href="css/index.css">
    <script src="scripts/chat.js"></script>
    <meta charset="UTF-8">
    <title>Чат</title>
</head>
<div class="chat-layout">
    <!-- верхняя часть (сообщения) -->
    <div class="chat-layout__messages" id="messages-container">
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user1</span> join</p>
        </div>
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user2</span> leave</p>
        </div>
        <div class="chat-layout__messages__message-to">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">You:</span> hello hello hello hello hello hello hello </p>
        </div>
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user3:</span> hello there</p>
        </div>
    </div>

    <!-- нижнаяя часть (ввод) -->
    <div class="chat-layout__client-wrapper">
        <div class="chat-layout__client-wrapper__input-wrapper">
            <input type="text" class="chat-layout__client-wrapper__input-wrapper__message-wrapper" id="message-input">
            <button class="chat-layout__client-wrapper__input-wrapper__send">SEND</button>
            </input>
        </div>
        <p class="chat-layout__client-wrapper__ip">you joined as 127:0:0:1</p>
    </div>
</div>

Нам понадобится знание нескольких приемов, позволяющих JS работать с DOM.

Чтобы обратиться к этому элементу из js, достаточно вызвать document.getElementById("id")

Для того, чтобы создать узел (например, div), нужно использовать функцию document.createElement("div")

Класс нового узла задается свойстром .className, содержимое — .innerHTML

При этом, т.к. HTML — это просто текст, иногда проще не генерировать узлы, а просто прописать те или иные параметры текстом через innerHTML (так мы пропишем <span> внутрь <p>)

Для того, чтобы добавить элемент внутрь другого, используется функция .appendChild()

Этого достаточно для того, чтобы написать функцию добавления сообщения

function addMessage(message) {
    //Создаем новое сообщение, указываем его класс
    var message_wrapper = document.createElement("div");
    message_wrapper.className = "chat-layout__messages__message-to";

    //Создаем новый текст сообщения, указываем его класс и содержимое
    var message_text = document.createElement("p");
    message_text.className = "chat-layout__messages__text";
    message_text.innerHTML = '<span class="chat-layout__messages__username">#You:</span> '+message;

    //Добавляем текст к сообщению
    message_wrapper.appendChild(message_text);

    //Обращаемся к контейнеру сообщений
    var messages = document.getElementById("messages-container");

    //Добаваляем к контейнеру новое сообщение
    messages.appendChild(message_wrapper);
}

Теперь, если вызвать нашу функцию из консоли (F12) с параметром — в чат добавится новое сообщение!

Но чего-то все еще не хватает...


Последнее, что мы можем сделать, не привлекая бекенд — добавлять сообщение не из консоли, а с помощью поля ввода.

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

function submitMessage()
{
    //Находим поле ввода
    var inputField = document.getElementById('message-input');
    var input = inputField.value;

    //Если сообщение не пустое
    if(input.length > 0){
        //Отправляем его, очищая поле ввода
        addMessage(input);
        inputField.value = '';
    }
}

Теперь нужно добавить скрипт к нажатию кнопки SEND. Самый простой способ это сделать — добавить вызов функции прямо в HTML:

<button class="chat-layout__client-wrapper__input-wrapper__send" onclick="submitMessage()">SEND</button>

Готово: при нажатии кнопки сообщение удаляется из поля ввода и отображается в чате. Вы восхитительны.


Итоговый HTML:

<head>
    <link rel="stylesheet" type="text/css" href="css/index.css">
    <script src="scripts/chat.js"></script>
    <meta charset="UTF-8">
    <title>Чат</title>
</head>
<div class="chat-layout">
    <!-- верхняя часть (сообщения) -->
    <div class="chat-layout__messages" id="messages-container">
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user1</span> join</p>
        </div>
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user2</span> leave</p>
        </div>
        <div class="chat-layout__messages__message-to">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">You:</span> hello hello hello hello hello hello hello </p>
        </div>
        <div class="chat-layout__messages__message-from">
            <p class="chat-layout__messages__text"><span class="chat-layout__messages__username">#user3:</span> hello there</p>
        </div>
    </div>

    <!-- нижнаяя часть (ввод) -->
    <div class="chat-layout__client-wrapper">
        <div class="chat-layout__client-wrapper__input-wrapper">
            <input type="text" class="chat-layout__client-wrapper__input-wrapper__message-wrapper" id="message-input">
            <button class="chat-layout__client-wrapper__input-wrapper__send" onclick="submitMessage()">SEND</button>
            </input>
        </div>
        <p class="chat-layout__client-wrapper__ip">you joined as 127:0:0:1</p>
    </div>
</div>

Итоговый JS:

function submitMessage()
{
    //Находим поле ввода
    var inputField = document.getElementById('message-input');
    var input = inputField.value;

    //Если сообщение не пустое
    if(input.length > 0){
        //Отправляем его, очищая поле ввода
        addMessage(input);
        inputField.value = '';
    }
}

function addMessage(message) {
    //Создаем новое сообщение, указываем его класс
    var message_wrapper = document.createElement("div");
    message_wrapper.className = "chat-layout__messages__message-to";

    //Создаем новый текст сообщения, указываем его класс и содержимое
    var message_text = document.createElement("p");
    message_text.className = "chat-layout__messages__text";
    message_text.innerHTML = '<span class="chat-layout__messages__username">#You:</span> '+message;

    //Добавляем текст к сообщению
    message_wrapper.appendChild(message_text);

    //Обращаемся к контейнеру сообщений
    var messages = document.getElementById("messages-container");

    //Добаваляем к контейнеру новое сообщение
    messages.appendChild(message_wrapper);
}