드디어 프론트의 마지막이다. 지난 2주 동안 배운 것 중 못 배웠던 부분들을 공부하고 마무리하는 시간이었다.
- 채팅 프로그램 UI만들기
- form tag
예전에 채팅 프로그램 UI를 만들었는데, 당시 부족했던 부분들을 더 보완하고자 한다.
입력을 할 때, <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
로 입력을 할 수 있다.return false
로 이벤트를 취소한다. 타이밍은 keydown 이후여야 한다.이미지를 끌어다 넣는 것이 아니라, 선택하면 입력창에 들어가야 한다. 이때, append
와 같이 내부에 추가하면 안된다. 이렇게 사용하면 단순한 이미지 객체 이동이 된다.
따라서 clone()
을 사용해서 객체를 복사한 뒤에 복사한 객체를 내부에 append
로 추가해줘야 한다
$("#econ01").on("click", function(){
$("#msg").append($(this).clone()); // 복사한 객체를 추가.
});
clone();
으로 객체를 복사 한 뒤에 추가해 준다.마지막으로 이모티콘창을 특정 이벤트 발생 시에만 보여지게 해주고 싶다. 그래서 제이쿼리의 애니메이션 기능이 있는 함수를 사용해서 구현하면 된다.
<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
를 적용한 뒤에 적용해야 동작한다.
fadeIn
은 hide
를 먼저 적용해줘야 한다.toggle
이 뒤에 달린 함수를 쓰면 된다. form
태그는 다른 요소들과 달리, 아주 중요한 기능이 있다. 먼저 form은 다음과 같이 입력을 받는 요소들과 함께 사용된다.
<form>
<input type="text">
<input type="password">
</form>
정확히는 input type=“text” / type=“password” / textarea
등등 입력 태그들은 form
태그와 함께 사용하는데, 이는 웹 어플리케이션의 구조 때문이다.
웹 어플리케이션은 크게 프론트와 백엔드로 나뉜다. 여기서 프론트는 html, css, js를 사용해서 효과와 동적인 액션을 구현하는 것이 목적이다. 이와 달리 백엔드는 실제 클라이언트의 요청에 따른 응답을 하는 비즈니스 로직을 구현하는 것이 목적이다.
즉, 프론트는 비즈니스 로직을 건드리지 않는다. 하지만 사용자는 프론트 화면에 정보를 입력한다. 따라서 프론트는 입력받는 데이터와 해당 요청을 백엔드로 넘겨줘야 한다.
조금 다른 얘기지만, 보안에 관련한 질문이 나왔었다. 그에 대한 답으로 프론트를 구성하는 언어는 높은 보안성을 가질 수 없는데, 이는 브라우저라는 환경에서 실행되긴 위해선 사용자의 컴퓨터에 오픈 소스로 실행되어야 하기 때문이다.
다만 ‘난독화’라는 아주 기본적인 보안 솔루션을 통해서 작성 코드를 쉽게 분석할 수 없도록 만들고, 기본적으로 프론트에선 전송 양식만 노출되기 때문에 안전하다.
프론트와 백엔드는 데이터 교환에 사용하는 것이 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
를 넣어주면 넘어갈 수 없는데, 다만 경고창 기능이 이미 설정되어 있어 커스텀 하기 어렵다.
이벤트 중에는 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
은 이벤트도 있다. 이를 활용해서 이벤트 처리가 가능하다.