• [Javascript] 카카오톡 클론 코딩 (매우 대충)

    2021. 5. 16.

    by. 안녕진

    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. 느낀점

    바닐라 문법을 전혀 모르는 것도 아닌데도 라이브러리를 쓰지 않으려는 습관을 고쳐야 될 것 같다.

    댓글