Day05:Set Chat Page(设定聊天页) II

全文同步於个人 Docusaurus Blog

在本章中,要达成两个目标:

  1. 使用 JS 来动态 render HTML 页面,产生一个小的对话框

  2. 当使用者输入名称进入 chat 後,当他在对话框输入讯息时, console.log 印出讯息,检查发出者是谁?输入什麽内容?

HTML & CSS

结构相较上一章,调整一个标签的 class,将 chat-container -> chat-list

  <body>
    <main class="wrapper">
      // ...
      <section class="chat-box display-none">
        // ...
        <div class="chat-list"></div>
      </section>
    </main>
  </body>

预先准备好一些简单的样式

.chat-list {
  height: 400px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  position: absolute;
  bottom: 1px;
  right: 5px;
}

.chat-container {
  margin: 0 10px;
  width: 300px;
  height: 100%;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  border: 1px solid #e5e5e5;
  background: #f2f8fd;
}

.chat-title-wrapper {
  height: 10%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(168.68deg, #0052c9 1.12%, #0a91db 100%);
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
}

.chat-title {
  width: 100%;
  margin: 0;
  padding: 0;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  text-align: center;
  font-size: 18px;
  color: #fff;
}

.message-container {
  width: 100%;
  height: 70%;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.message-input-wrapper {
  width: 100%;
  height: 20%;
  display: flex;
  justify-content: center;
  align-items: flex-end;
}

.message-input {
  width: 100%;
  height: 40px;
  border: 1px solid #d5deeb;
  background-color: #fff;
  font-size: 16px;
}

.message-content {
  width: 100%;
}

.message-paragraph {
  font-size: 16px;
  margin-left: 5px;
  margin-top: 5px;
  margin-right: 5px;
}

.message-author {
  font-weight: bold;
}

修正进入页验证

原先的 client.js 在验证进入时,写法存在瑕疵,会出现输入使用者名称时不断触发的问题,所以调整成当点击进入时,才进行验证和跳转。

// client.js
nameInput.addEventListener('keyup', (e) => {
  store.setUserName(e.target.value);
});

chatBtn.addEventListener('click', () => {
  const checkName = store.getUserName();
  // validation can't be empty
  if (checkName) {
    ui.goToChat();
  }
});

Render HTML

touch element.js

element.js

在原先的 .chat-list 标签底下,动态 render,同时预计传入数个参数,用於抓取动态生成的标签。

const getChatList = (data) => {
  const { chatTitle, messageContainerID, messageInputID, chatContainerID } =
    data;

  const chatContainer = document.createElement('div');
  chatContainer.classList.add('chat-container');
  chatContainer.setAttribute('id', chatContainerID);

  // render
  chatContainer.innerHTML = `
    <div class="chat-title-wrapper">
      <p class="chat-title">${chatTitle}</p>
    </div>
    <div class="message-container" id="${messageContainerID}">
      <div class="message-content">
        <p class="message-paragraph">
          <span class="message-author">Pitt:</span>Hello Websocket
        </p>
      </div>
    </div>
    <div class="message-input-wrapper">
      <input
        type="text"
        class="message-input"
        id="${messageInputID}"
        placeholder="Type Something"
      />
    </div>
  `;

  return chatContainer;
};

export default {
  getChatList,
};

Get User Name & Message

建立 data 的预设值

// ui.js
const messageContainerID = 'message-container-id';
const messageInputID = 'message-input-id';
const chatContainerID = 'chatContainerID';

const createChatList = () => {
  // default value
  const data = {
    chatTitle: 'Group Name',
    messageContainerID,
    messageInputID,
    chatContainerID,
  };
};

导入刚刚的用来 render 的 elemednt.js,抓取最外层的 .chat-list,透过 appendChild() 来添加子元素。

import element from './element.js';

const createChatList = () => {
  // ...
  const chatContainer = element.getChatList(data);
  const chatListElement = document.querySelector('.chat-list');
  chatListElement.appendChild(chatContainer);
};

抓取输入框的 DOM,监听使用者触发的事件,当输入完成按下 Enter 按钮时,除了抓取使用者名称,同时也印出输入内容。

const createChatList = () => {
  // ...
  const messageInput = document.getElementById(messageInputID);
  messageInput.addEventListener('keydown', (event) => {
    const key = event.key;

    if (key === 'Enter') {
      const author = store.getUserName();
      const messageContent = event.target.value;

      messageInput.value = '';
      console.log({
        author,
        messageContent,
      });
    }
  });
};

<<:  【Day 21】JavaScript 函式

>>:  Unity与Photon的新手相遇旅途 | Day6-粒子效果应用范例

安装 elementary OS 6.0 与呒虾米

前言 elementary OS 6.0 (以下称 Odin) 释出後几天,我决定也来安装看看,想不...

EP19 - RE:从零开始学习本机操作 EKS 并手动部署

在 EP18 - 欢迎来到容器管理工具的 EKS, 我们使用 Terraform 搭配 EKS mo...

负责任的机器学习专案

机器学习的应用程序,介於使用者面向服务、统计学和计算机科学有所交集的领域。使用者面向服务包含个别用户...

[Day25]Primary Arithmetic

上一篇介绍了Funny Encryption Method,这题介绍了当1个数字是十进位以及十六进位...

[Golang] Map

A map is an unordered collection of key-value pair...