-
1. 구현한 화면
그림판으로 로딩 화면을 만들었다. 하모니카os에서 작업을 하려니 익숙하지 않아서 너무 불편했다.
친구 목록 화면이다. 배경은... 애초에 javascript랑 css 작성을 익히는 목적이었으니까,
할 줄 아는 건 안해도 된다고 합리화 하며 스킵했다.
친구 추가 기능과 검색 기능을 넣었다.
채팅 목록 화면. 친구 목록과 매우 비슷하다. 처음에 div들에 css를 적용시키려고 id를 부여했었는데, 어차피 한 html 파일에 모든 화면을 구현했기 때문에 비슷한 element들은 class를 부여했으면 더 깔끔했을 것 같다.
이건 채팅방 화면이다.
친구 목록에서 친구추가하면 순서대로 고유번호를 부여하는데, 이 고유번호로 채팅방을 구분한다.
단체 채팅방은 구현하지 않았다.
채팅도 전송하면 1~10초 뒤에 아진짜?라고 답장하는 형식으로 만들었다.
git blog에 구현을 해놨다. 다음에 github 말고 server side를 구현할 수 있는 곳에서 다시 비슷한 작업을 한다면, 사용자들이 직접 채팅할 수 있도록 만들 생각이다.
2. 코드
- HTML
1. 구현한 세 개의 화면(친구목록, 채팅목록, 채팅방)을 div로 구분했다.
div로 구분하여 각각의 view를 보여줄 때만 display: none; 속성을 삭제해서 보이도록 만들었다.
하나의 Application인데 페이지를 이동하면서 구현하면, 뭔가 한 App이라는 느낌이 살지 않을 것 같아서 이렇게 만들었다.
2. id = friends_list, chat_list, chat로 div를 만들어서, 친구,채팅방,채팅내용이 추가되면 DOM을 생성해서 append하여 화면에 바로 추가되도록 만들었다.
<div id='friend_list_view'> <div style='height: 30px;'> <span style='position: absolute; left: 10px;'>친구</span> <span style='position: absolute; right: 10px; top:5px;'><button style='font-size:25px;' onclick='add_friend();'>+</button></span> </div> <div style='height: 30px;'> <input onKeyPress='if (event.keyCode==13) {search_name();}' style='width: 240px;' id='name-search-box' type='text' placeholder='이름 검색'> </div> <div style='height: 420px;' id="friends_list"> </div> </div> <div id='chat_list_view' style='display: none;'> <div style='height: 30px;'> <span style='position: absolute; left: 10px;'>채팅</span> </div> <div style='height: 30px;'> <input onKeyPress='if (event.keyCode==13) {search_chat();}' style='width: 240px;' id='chat-search-box' type='text' placeholder='채팅방 이름, 참여자 검색'> </div> <div style='height: 420px;' id="chat_list"> </div> </div> <div id='chat_room_view' style='display: none;'> <div style='height: 30px;'> <span style='position: absolute; left: 0px; width: 100%; text-align: center;' id='chat_room_name'></span> </div> <div style='height: 420px;' id="chat"> </div> <div style='display: flex; height: 30px; align-items: center;' id="input_chat"> <input id='msg_input' style='position: absolute; left: 10px; width: 70%;' type='text' onKeyPress='if (event.keyCode==13) {send_btn();}'> <a style='position: absolute; right: 10px;' href='javascript:void(0);' onclick='send_btn();'>전송</a> </div> </div>
-Javascript
Friend, Chat, Msg 클래스를 구현했다.
var friends = [] var searched_friends = [] var friend_count = 0; var chats = [] var searched_chats = [] var current_room_no = -1; class Friend { constructor(name, unique_num) { this.name = name; this.unique_num = unique_num; } } class Chat { constructor(participant) { this.participant = participant; this.chat_data = []; this.unique_num = this.participant.unique_num; } } class Msg { constructor(name, time, msg) { this.name = name; this.time = time; this.msg = msg; } } function send_btn() { var Now = new Date(); var NowTime = Now.getFullYear(); NowTime += '-' + Now.getMonth() + 1 ; NowTime += '-' + Now.getDate(); NowTime += ' ' + Now.getHours(); NowTime += ':' + Now.getMinutes(); NowTime += ':' + Now.getSeconds(); var msg = $('#msg_input').val(); send("me", NowTime, msg); setTimeout('ai_send('+current_room_no+')', Math.round(Math.random() * 10000)); } function ai_send(unique_num) { var Now = new Date(); var NowTime = Now.getFullYear(); NowTime += '-' + Now.getMonth() + 1 ; NowTime += '-' + Now.getDate(); NowTime += ' ' + Now.getHours(); NowTime += ':' + Now.getMinutes(); NowTime += ':' + Now.getSeconds(); for (var i = 0; i < friends.length; i++) { if (friends[i].unique_num === unique_num) { send(friends[i].name, NowTime, "아진짜?"); break; } } } function send(name, NowTime, msg) { for (var i = 0; i < chats.length; i++) { if (chats[i].unique_num === current_room_no) { chats[i].chat_data.push(new Msg(name, NowTime, msg)); $('#msg_input').val(''); break; } } if (name === "me") { $('#chat').html($('#chat').html() + "<p style='text-align: right; margin: 0px 5px;'>" + name + " - " + NowTime + "<br>" + msg + "</p>"); } else { $('#chat').html($('#chat').html() + "<p style='text-align: left; margin: 0px 5px;'>" + name + " - " + NowTime + "<br>" + msg + "</p>"); } } function start_chat_room(unique_num) { for (var i = 0; i < chats.length; i++) { if (chats[i].unique_num === unique_num) { enter_chat_room(unique_num); return; } } create_chat_room(unique_num); enter_chat_room(unique_num); } function enter_chat_room(unique_num) { $('#chat').html(''); for (var i = 0; i < friends.length; i++) { if (friends[i].unique_num === unique_num) { $('#chat_room_name').text(friends[i].name); break; } } for (var i = 0; i < chats.length; i++) { if (chats[i].unique_num === unique_num) { for (var j = 0 ; j < chats[i].chat_data.length; j++) { if (chats[i].chat_data[j].name === "me") { $('#chat').html($('#chat').html() + "<p style='text-align: right; margin: 0px 5px;'>" + chats[i].chat_data[j].name + " - " + chats[i].chat_data[j].time + "<br>" + chats[i].chat_data[j].msg + "</p>"); } else { $('#chat').html($('#chat').html() + "<p style='text-align: left; margin: 0px 5px;'>" + chats[i].chat_data[j].name + " - " + chats[i].chat_data[j].time + "<br>" + chats[i].chat_data[j].msg + "</p>"); } } break; } } show_chat_room(); current_room_no = unique_num; } function create_chat_room(unique_num) { var friend; for (var i = 0; i < friends.length; i++) { if (friends[i].unique_num === unique_num) { friend = friends[i] } } var chat = new Chat(friend); chats.push(chat); var chat_list_div = document.getElementById("chat_list"); var new_div = document.createElement("a"); new_div.innerText = chat.participant.name; new_div.setAttribute("href", "javascript:void(0);"); new_div.setAttribute("class", "chat_obj"); new_div.setAttribute("unique_num", chat.unique_num); new_div.setAttribute("onclick", "enter_chat_room(" + chat.unique_num + ")"); chat_list_div.appendChild(new_div); } function add_friend() { var friend_name = prompt("추가할 친구 이름을 입력하세요."); if (friend_name === "") {return;} if (friend_name === null) {return;} var new_friend = new Friend(friend_name, friend_count); friend_count += 1; friends.push(new_friend); var friends_list_div = document.getElementById("friends_list"); var new_div = document.createElement("a"); new_div.innerText = friend_name; new_div.setAttribute("href", "javascript:void(0);"); new_div.setAttribute("class", "friend_obj"); new_div.setAttribute("unique_num", new_friend.unique_num); new_div.setAttribute("onclick", "start_chat_room(" + new_friend.unique_num + ")"); friends_list_div.appendChild(new_div); } function search_name() { searched_friends = [] friend_name = document.getElementById('name-search-box').value if (friend_name === "") { show_list(friends); return; } if (friend_name === null) { return; } for (var i = 0; i < friends.length; i++) { if (friends[i].name.includes(friend_name)) { searched_friends.push(friends[i]); } } show_list(searched_friends); } function show_list(list) { show_friend_list(); var friend_objs = document.getElementsByClassName("friend_obj"); for (var i = friend_objs.length - 1; i >= 0; i--) { var parent = friend_objs[i].parentElement; parent.removeChild(friend_objs[i]); } if (list.length === 0) {return;} for (var i = 0; i < list.length; i++) { var friends_list_div = document.getElementById("friends_list"); var new_div = document.createElement("a"); new_div.innerText = list[i].name; new_div.setAttribute("href", "javascript:void(0);"); new_div.setAttribute("class", "friend_obj"); new_div.setAttribute("unique_num", list[i].unique_num); new_div.setAttribute("onclick", "start_chat_room(" + list[i].unique_num + ")"); friends_list_div.appendChild(new_div); } } function load_cowtalk() { setTimeout("after_loading();", 2000); } function after_loading() { document.getElementById("main_img").height = "0px"; document.getElementById("main_img").width = "0px"; display_main_menu(); } function display_main_menu() { document.getElementById("main_menu").style.display = "inline-flex"; } function show_friend_list() { $('#friend_list_view').css("display", ""); $('#chat_list_view').css("display", "none"); $('#chat_room_view').css("display", "none"); } function show_chat_list() { $('#friend_list_view').css("display", "none"); $('#chat_list_view').css("display", ""); $('#chat_room_view').css("display", "none"); } function show_chat_room() { $('#friend_list_view').css("display", "none"); $('#chat_list_view').css("display", "none"); $('#chat_room_view').css("display", ""); }
3. 느낀점
바닐라 문법을 전혀 모르는 것도 아닌데도 라이브러리를 쓰지 않으려는 습관을 고쳐야 될 것 같다.
'개발 > 개인 프로젝트' 카테고리의 다른 글
[기억하다] 일상 루틴 / 학습 기억 보조 앱 (0) 2022.08.24 [Flutter] 운동 보조 앱 "헬생" (0) 2022.02.18 [node.js/express] 학교 공지사항 크롤링 API 백엔드 서버 (0) 2022.02.09 C# 소켓, 스레드를 이용한 채팅 프로그램 (0) 2020.01.07 댓글