Day 46. 웹 프론트 12 ( 채팅 UI 구현 )

ho_c·2022년 4월 20일
0

국비교육

목록 보기
45/71
post-thumbnail
post-custom-banner

드디어 프론트의 마지막이다. 지난 2주 동안 배운 것 중 못 배웠던 부분들을 공부하고 마무리하는 시간이었다.

📝목차

  1. 채팅 프로그램 UI만들기
  2. form tag

예전에 채팅 프로그램 UI를 만들었는데, 당시 부족했던 부분들을 더 보완하고자 한다.

1. 채팅 프로그램 UI만들기

(1) contenteditable 속성

입력을 할 때, <input type=text>, <textarea> 같은 입력 전용 요소를 사용하는데, 이 둘은 한계가 있다. 먼저 text 는 enter가 먹히지 않고, textarea 는 text만 받기 때문에 이모티콘이나, 이미지를 보낼 수 없다.

따라서 div 로 채팅 입력창을 만들어 준다. 물론 div 가 입력 전용 요소는 아니지만 contenteditable 속성을 활성화하면 입력이 가능하다.

<div id="chat" contenteditable="true"></div>

이제 div 에다 입력하고 엔터를 치면, 내부에 입력 내용이 들은 하위 div를 만들어 낸다. 그리고 내부에는 html 형식으로 이미지도 함께 넣어줄 수 있다.

다만 문제는 contenteditable 의 기본 동작이다. 입력 후 엔터를 치게 되면 먼저 ‘한 행’을 내리고 입력 내용을 <div>으로 감싼다. 그래서 내용을 append(); 시킬 때, <br>태그도 같이 들어가게 된다. 따라서 returm false; 로 해당 이벤트를 취소시킨다.

또 다른 문제는 타이밍이다. 흔히 이벤트 리스너를 keyup에 걸어두는데, 위의 기본 동작은 keydown keyup 사이에 일어난다. 따라서 이벤트 리스너를 keydown 으로 설정해놓는다.

    <div id="container">

        <div id="chat"></div>

        <div id="msg" contenteditable="true"></div>
    </div>

    <script>

        $("#msg").on("keydown", function (e) {
		// 입력시 줄바꿈 가능
            if (e.keyCode == 13 && e.shiftKey == false) {  
                let text = $("#msg").html(); // 요소도 적힌 html을 가져와야 정상 입력이 된다.

                let chatDiv = $('<div class="msgbox">');
                chatDiv.html(text); 

                chatDiv.hide();
                chatDiv.fadeIn(1000);

                $("#chat").append(chatDiv);
                $("#chat").append("<br>");
                
                $("#msg").html(""); 
                $("#chat").focus();
                $('#chat').scrollTop($('#chat').prop('scrollHeight'));

                return false; 
            }
        })
	</script>

< 요약 >

  • div로 입력을 할 수 있다.
  • 이미지도 입력할 수 있다는 이점이 있다. (html로 끌어와야, 이미지를 넣는다.)
  • 하지만 입력 후, 엔터를 치면 한 줄씩 줄바꿈을 한다.
  • 이것도 html로 끌려오는 것이 문제니, 해당 동작을 취소시켜야 한다.
  • return false 로 이벤트를 취소한다. 타이밍은 keydown 이후여야 한다.

(2) clone(); 이모티콘 넣기

이미지를 끌어다 넣는 것이 아니라, 선택하면 입력창에 들어가야 한다. 이때, append와 같이 내부에 추가하면 안된다. 이렇게 사용하면 단순한 이미지 객체 이동이 된다.

따라서 clone()을 사용해서 객체를 복사한 뒤에 복사한 객체를 내부에 append로 추가해줘야 한다

$("#econ01").on("click", function(){
	$("#msg").append($(this).clone());  // 복사한 객체를 추가.
});

< 요약 >

  • append를 할 때, 그냥 하면 객체가 이동하는게 되어버린다.
  • clone(); 으로 객체를 복사 한 뒤에 추가해 준다.

(3) hide(), show()

마지막으로 이모티콘창을 특정 이벤트 발생 시에만 보여지게 해주고 싶다. 그래서 제이쿼리의 애니메이션 기능이 있는 함수를 사용해서 구현하면 된다.

    <div id="box"></div>
    <button id="show">show</button>
    <button id="hide">hide</button>

    <script>
        $(function () {
            $("#show").on("click", function () {
                $("#box").show(1000, function () { // sildeUp, fadeIn
                    alert("나타나기 끝")
                });
            });
            $("#hide").on("click", function () {
                $("#box").hide(1000, function () {  // sildeDown, fadeOut

                    alert("감추기 끝")
                });
            });
        });
    </script>

hide 말고도 sildeDown-Up, fadeIn-Out 같은 함수들도 추가적으로 존재한다. 이때, fadeIn 은 먼저 hide를 적용한 뒤에 적용해야 동작한다.

< 요약 >

  • 애니메이션을 구현하는 함수들이 존재한다. 물론 CSS로도 구현이 가능하다.
  • fadeInhide를 먼저 적용해줘야 한다.
  • 하나의 리소스에 두 개가 동시 동작하려면 toggle이 뒤에 달린 함수를 쓰면 된다.

2. form tag

form 태그는 다른 요소들과 달리, 아주 중요한 기능이 있다. 먼저 form은 다음과 같이 입력을 받는 요소들과 함께 사용된다.

<form>
        <input type="text">
        <input type="password">
</form>

정확히는 input type=“text” / type=“password” / textarea 등등 입력 태그들은 form 태그와 함께 사용하는데, 이는 웹 어플리케이션의 구조 때문이다.

(1) 프론트와 백엔드

웹 어플리케이션은 크게 프론트와 백엔드로 나뉜다. 여기서 프론트는 html, css, js를 사용해서 효과와 동적인 액션을 구현하는 것이 목적이다. 이와 달리 백엔드는 실제 클라이언트의 요청에 따른 응답을 하는 비즈니스 로직을 구현하는 것이 목적이다.

즉, 프론트는 비즈니스 로직을 건드리지 않는다. 하지만 사용자는 프론트 화면에 정보를 입력한다. 따라서 프론트는 입력받는 데이터와 해당 요청을 백엔드로 넘겨줘야 한다.

(2) 프론트의 보안성

조금 다른 얘기지만, 보안에 관련한 질문이 나왔었다. 그에 대한 답으로 프론트를 구성하는 언어는 높은 보안성을 가질 수 없는데, 이는 브라우저라는 환경에서 실행되긴 위해선 사용자의 컴퓨터에 오픈 소스로 실행되어야 하기 때문이다.

다만 ‘난독화’라는 아주 기본적인 보안 솔루션을 통해서 작성 코드를 쉽게 분석할 수 없도록 만들고, 기본적으로 프론트에선 전송 양식만 노출되기 때문에 안전하다.


(3) 사용법

프론트와 백엔드는 데이터 교환에 사용하는 것이 form 태그로 입력받는 데이터를 서버에 보내는 역할을 하며, submit reset action 을 사용한다.

- action 속성 : 입력한 내용을 백엔드 프로그램으로 보낼 때, 해당 프로그램의 위치를 적는 속성이다. 값으로 프로그램의 경로를 넣어주면 된다.

 <form action=“login.html”>

- submit : input 태그의 타입 중에 하나로, 해당 요소를 누르면 자동으로 입력된 내용을 액션에 설정된 파일로 전송 후, 이동한다.

<form>
	<input type="text">
        <input type="password">
        <input type="submit" value="제출">
</form>

- reset : 입력된 내용을 초기화 시킨다.

이 세 가지는 입력 UI에서 함께 묶여서 사용이 된다. 또한 입력을 무조건 받아야되는 경우 속성으로 required를 넣어주면 넘어갈 수 없는데, 다만 경고창 기능이 이미 설정되어 있어 커스텀 하기 어렵다.


(4) onsubmit Event

이벤트 중에는 onsubmit가 있으며, 이는 입력값을 전송하는 이벤트에 핸들러를 설정해줄 수 있으며, return false 로 전송을 취소시킬 수 있다.

       $("#frm").on("submit", function(){
            // 값 끌어오기
            let id = $("#id").val();
            let pw = $("#pw").val();
            let name = $("#name").val();
            let phone = $("#phone").val();
            let email = $("#email").val();


            // 정규표현식 객체 생성
            // id regex
            let regexId = /^[a-z]{1}[a-z\d_]{7,13}$/g;

            // pw regex
            let regexPw = /^[.\d\Da-zA-Z?*!#$%]{8,16}$/g;
            
            // name regex
            let regexName = /^[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]{3,5}$/g;
            
            // phone regex
            let regexPhone = /^01[\d]-*[\d]{4}-*[\d]{4}$/g;
            
            // email regex
            let regexEmail = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;

            // 유효성 검사
            if(!(regexId.test(id))){
                alert("ID를 다시 입력해주세요");
                $("#id").val('');
                $("#id").focus();
                return false;
            } else if(!(regexPw.test(pw))){
                alert("PW를 다시 입력해주세요");
                $("#pw").val('');
                $("#pw").focus();
                return false;
            } else if(!(regexName.test(name))){
                alert("이름을 다시 입력해주세요");
                $("#name").val('');
                $("#name").focus();
                return false;
            } else if(!(regexPhone.test(phone))){
                alert("핸드폰 번호를 다시 입력해주세요");
                $("#phone").val('');
                $("#phone").focus();
                return false;
            } else if(!(regexEmail.test(email))){
                alert("이메일을 다시 입력해주세요");
                $("#email").val('');
                $("#email").focus();
                return false;
            }

        });

        $("#pw-check").on("keyup", function(){
            let pw = $("#pw").val();
            let check = $("#pw-check").val();

            if(pw == check){
                $("#pwCheckMsg").text("비밀번호가 일치합니다.");
                $("#pwCheckMsg").css("color", "blue");
            } else {
                $("#pwCheckMsg").text("비밀번호을 확인하세요");
                $("#pwCheckMsg").css("color", "red");
            }
        });

< 요약 >

  • 프론트와 백엔드는 데이터 교환을 한다.
  • 교환에 사용하는 태그가 form 이다.
  • 입력 태그들을 form 으로 묶어주면, 서버에 전송할 수 있다.
  • submit : 자동 전송 / action : 전송 위치 / reset : 입력값 초기화
  • submit 은 이벤트도 있다. 이를 활용해서 이벤트 처리가 가능하다.
profile
기록을 쌓아갑니다.
post-custom-banner

0개의 댓글