溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

構(gòu)建一個即時消息應用之實現(xiàn)Home頁面

發(fā)布時間:2021-10-26 11:52:13 來源:億速云 閱讀:183 作者:iii 欄目:編程語言

這篇文章主要介紹“構(gòu)建一個即時消息應用之實現(xiàn)Home頁面”,在日常操作中,相信很多人在構(gòu)建一個即時消息應用之實現(xiàn)Home頁面問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”構(gòu)建一個即時消息應用之實現(xiàn)Home頁面”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

對話表單

構(gòu)建一個即時消息應用之實現(xiàn)Home頁面

轉(zhuǎn)到 static/ages/home-page.js 文件,在 HTML 視圖中添加一些標記。

 
<form id="conversation-form">     <input type="search" placeholder="Start conversation with..." required> </form>

將該表單添加到我們顯示 “auth user” 和 “l(fā)ogout” 按鈕部分的下方。

page.getElementById('conversation-form').onsubmit = onConversationSubmit

現(xiàn)在我們可以監(jiān)聽 “submit” 事件來創(chuàng)建對話了。

import http from '../http.js' import { navigate } from '../router.js'  async function onConversationSubmit(ev) {     ev.preventDefault()      const form = ev.currentTarget     const input = form.querySelector('input')      input.disabled = true      try {         const conversation = await createConversation(input.value)         input.value = ''         navigate('/conversations/' + conversation.id)     } catch (err) {         if (err.statusCode === 422) {             input.setCustomValidity(err.body.errors.username)         } else {             alert(err.message)         }         setTimeout(() => {             input.focus()         }, 0)     } finally {         input.disabled = false     } }  function createConversation(username) {     return http.post('/api/conversations', { username }) }

在提交時,我們使用用戶名對 /api/conversations 進行 POST 請求,并重定向到 conversation 頁面(用于下一篇文章)。

對話列表

構(gòu)建一個即時消息應用之實現(xiàn)Home頁面

還是在這個文件中,我們將創(chuàng)建 homePage() 函數(shù)用來先異步加載對話。

export default async function homePage() {     const conversations = await getConversations().catch(err => {         console.error(err)         return []     })     /*...*/ }  function getConversations() {     return http.get('/api/conversations') }

然后,在標記中添加一個列表來渲染對話。

<ol id="conversations"></ol>

將其添加到當前標記的正下方。

const conversationsOList = page.getElementById('conversations') for (const conversation of conversations) {     conversationsOList.appendChild(renderConversation(conversation)) }

因此,我們可以將每個對話添加到這個列表中。

import { avatar, escapeHTML } from '../shared.js'  function renderConversation(conversation) {     const messageContent = escapeHTML(conversation.lastMessage.content)     const messageDate = new Date(conversation.lastMessage.createdAt).toLocaleString()      const li = document.createElement('li')     li.dataset['id'] = conversation.id     if (conversation.hasUnreadMessages) {         li.classList.add('has-unread-messages')     }     li.innerHTML = `         <a href="/conversations/${conversation.id}">             <div>                 ${avatar(conversation.otherParticipant)}                 <span>${conversation.otherParticipant.username}</span>             </div>             <div>                 <p>${messageContent}</p>                 <time>${messageDate}</time>             </div>         </a>     `     return li }

每個對話條目都包含一個指向?qū)υ掜撁娴逆溄?,并顯示其他參與者信息和最后一條消息的預覽。另外,您可以使用 .hasUnreadMessages 向該條目添加一個類,并使用 CSS 進行一些樣式設(shè)置。也許是粗體字體或強調(diào)顏色。

請注意,我們需要轉(zhuǎn)義信息的內(nèi)容。該函數(shù)來自于 static/shared.js 文件:

export function escapeHTML(str) {     return str         .replace(/&/g, '&amp;')         .replace(/</g, '&lt;')         .replace(/>/g, '&gt;')         .replace(/"/g, '&quot;')         .replace(/'/g, '&#039;') }

這會阻止將用戶編寫的消息顯示為 HTML。如果用戶碰巧編寫了類似以下內(nèi)容的代碼:

<script>alert('lololo')</script>

這將非常煩人,因為該腳本將被執(zhí)行?。所以,永遠記住要轉(zhuǎn)義來自不可信來源的內(nèi)容。

消息訂閱

最后但并非最不重要的一點,我想在這里訂閱消息流。

const unsubscribe = subscribeToMessages(onMessageArrive) page.addEventListener('disconnect', unsubscribe)

在 homePage() 函數(shù)中添加這一行。

function subscribeToMessages(cb) {     return http.subscribe('/api/messages', cb) }

函數(shù) subscribe() 返回一個函數(shù),該函數(shù)一旦調(diào)用就會關(guān)閉底層連接。這就是為什么我把它傳遞給 “斷開連接”disconnect事件的原因;因此,當用戶離開頁面時,事件流將被關(guān)閉。

async function onMessageArrive(message) {     const conversationLI = document.querySelector(`li[data-id="${message.conversationID}"]`)     if (conversationLI !== null) {         conversationLI.classList.add('has-unread-messages')         conversationLI.querySelector('a > div > p').textContent = message.content         conversationLI.querySelector('a > div > time').textContent = new Date(message.createdAt).toLocaleString()         return     }      let conversation     try {         conversation = await getConversation(message.conversationID)         conversation.lastMessage = message     } catch (err) {         console.error(err)         return     }      const conversationsOList = document.getElementById('conversations')     if (conversationsOList === null) {         return     }      conversationsOList.insertAdjacentElement('afterbegin', renderConversation(conversation)) }  function getConversation(id) {     return http.get('/api/conversations/' + id) }

每次有新消息到達時,我們都會在 DOM 中查詢會話條目。如果找到,我們會將 has-unread-messages 類添加到該條目中,并更新視圖。如果未找到,則表示該消息來自剛剛創(chuàng)建的新對話。我們?nèi)プ鲆粋€對 /api/conversations/{conversationID} 的 GET 請求,以獲取在其中創(chuàng)建消息的對話,并將其放在對話列表的前面。

到此,關(guān)于“構(gòu)建一個即時消息應用之實現(xiàn)Home頁面”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI