簡單聊天室
阿新 • • 發佈:2022-05-28
演示
html
<div id="firstStep"> <input type="text" placeholder="輸入使用者名稱" id="username"/> <button id="inter">進入聊天室</button> <div id="message" style="color:red"></div> </div> <div id="secondStep" style="display: none;"> <div id="infobox" class="infobox"> <span id="upButton">↑</span> </div> <input type="text" id="input" placeholder="輸入資訊..."/> <button id="send">傳送</button> <div id="message2" style="color:red"></div> <p id="userHeader"></p> </div>
JS
const input=document.getElementById('input') const send=document.getElementById('send') const infobox=document.getElementById('infobox') const inter=document.getElementById('inter') const username=document.getElementById('username') const color=['#45C195','#C5517D','#C4904E','#B5CD69','#4E91C4','#B364CB','#C8B35D','#3AADAA','#8A40BE','#C24C8B'] const upButton=document.getElementById('upButton') // 使用者名稱稱與字型顏色 let name let textColor // 型別 const TYPE_ENTER=0 const TYPE_MSG=1 const TYPE_CLOSE=2 // socket let socket inter.addEventListener('click',()=>{ // 01 設定使用者名稱 if(username.value===''){ document.getElementById('message').innerHTML='請輸入使用者名稱!' return } name=username.value document.getElementById('userHeader').innerHTML='使用者:'+name // 02 為使用者設定顏色 textColor=color[Math.floor(Math.random()*10)] // 03 切換顯示 const firstStep=document.getElementById('firstStep') const secondStep=document.getElementById('secondStep') firstStep.style.display='none' secondStep.style.display='block' // 04 進入聊天室 socket = new WebSocket('ws://localhost:8001'); socket.addEventListener('open', function (event) { let userInfo={ username:name, type:TYPE_ENTER, } socket.send(JSON.stringify(userInfo)); }); // 05 接受資訊 socket.addEventListener('message', function (event) { const data=JSON.parse(event.data) let div = document.createElement('div'); div.innerHTML = data.msg if(data.type===TYPE_ENTER||data.type===TYPE_CLOSE){ div.style.color = 'rgb(151 151 151)' }else{ div.style.color = data.color } let span=document.createElement('span') span.innerHTML='-----'+new Date().toLocaleTimeString() div.appendChild(span) document.getElementById('infobox').appendChild(div) infobox.scrollTop=infobox.scrollHeight-infobox.offsetHeight //儲存檢視在底部 }); // 06 傳送資訊 send.addEventListener('click',()=>{ sendMessage() }) document.addEventListener('keyup',(e)=>{ if (e.code === 'Enter') { sendMessage() } }) upButton.addEventListener('click',()=>{ infobox.scrollTop=0 }) }) function sendMessage(){ const message2=document.getElementById('message2') if(input.value===''){ message2.innerHTML='訊息不能為空' return } message2.innerHTML='' let userInfo={ type:TYPE_MSG, color:textColor, msg:input.value } socket.send(JSON.stringify(userInfo)) input.value='' }
CSS
.infobox{ padding: 10px; border: 1px solid rgb(186, 183, 183); width: 500px; height: 200px; margin-bottom: 10px; overflow: auto; box-sizing: border-box; position: relative; } #upButton{ width: 30px; height: 30px; position: fixed; background-color: #eee; top: 165px; border-radius: 15px; display: flex; justify-content: center; align-items: center; font-size: 20px; cursor: pointer; left: 450px; }
伺服器
npm i nodejs-websocket
// app.js
var ws = require("nodejs-websocket")
const TYPE_ENTER=0
const TYPE_MSG=1
const TYPE_CLOSE=2
var server = ws.createServer(function (connection) {
connection.on("text", function (data) {
const info=JSON.parse(data)
if(info.type===TYPE_ENTER){
connection.username=info.username // 每個連線有個使用者名稱
const msg=connection.username+'進入聊天室'
broadcast(JSON.stringify({ // 廣播資訊
msg,
type:TYPE_ENTER
}))
}else if(info.type===TYPE_MSG){
const msg=connection.username+':'+info.msg
broadcast(JSON.stringify({
msg,
type:TYPE_MSG,
color:info.color
}))
}
})
connection.on("close", function (code, reason) {
const msg=connection.username+'離開聊天室'
broadcast(JSON.stringify({
msg,
type:TYPE_CLOSE
}))
})
connection.on('error',(err)=>{
console.log('異常:',err)
})
}).listen(8001)
function broadcast(msg){
server.connections.forEach(item=>{
item.send(msg)
})
}
node app.js