<select>
- HTML에서 사용 되는 폼 요솔, 드롭다운 리스트 또는 선택 박스를 생성하는 데에 사용된다.
- <select> 요소 안에 여러 개의 <option> 요소를 포함하여 각 항목을 정의한다.
- 선택시 input, change 이벤트가 발생한다.
- value로 유저가 입력한 값을 가져올 수 있다.
<form class="container my-5 form-group">
<p>상품선택</p>
<select class="form-select mt-2">
<option>모자</option>
<option>셔츠</option>
</select>
</form>
(▲ Bootstrap이 설치되어 있으면 예쁘게 나옴)
Q. 사용자가 셔츠를 선택하면 하단에 사이즈를 선택할 수 있는 <select> 박스가 나타나게 하려면?
<form class="container my-5 form-group">
<p>상품선택</p>
<select class="form-select mt-2">
<option>모자</option>
<option>셔츠</option>
</select>
<select class="form-select mt-2 form-hide">
<option>95</option>
<option>100</option>
</select>
</form>
미리 <select>를 하나 더 추가하고, .form-hide 클래스에는 display: none을 주었다.
<script>
if ($('.form-select').eq(0).val() == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
</script>
그리고 사용자가 선택한 값이 셔츠이면 form-hide클래스를 제거해 달라고 코드를 짰지만 실행하면 기능은 작동은 하지 않는다.
* <script>안에 적은 코드는 페이지 로드시 1회 실행됨 *
사용자가 셔츠를 선택하면 form-hide를 제거해 달라고 코드를 짰는데, 이 코드는 <script> 안에 적었기 때문에 페이지 로드시 1회 실행되고 다시는 실행되지 않는다. 그래서 저 코드를 <select>를 조작할 때마다 실행한다면 의도대로 잘 동작할 것이다.
<script>
$('.form-select').eq(0).on('input', function(){
if ($('.form-select').eq(0).val() == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
});
</script>
▲ <input>이나 <select> 조작할 때 input 이벤트가 발생하기 때문에 input 이벤트 리스너를 부착했다.
실행하면 잘 동작한다.
(응용 1) '모자' 선택했을 때 <select>를 다시 숨기는 기능 만들기
<script>
$('.form-select').eq(0).on('input', function(){
if ($('.form-select').eq(0).val() == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
} else {
$('.form-select').eq(1).addClass('form-hide'); // 추가
}
});
</script>
(응용 2) 비슷한 셀렉터들이 많으니 변수화하여 성능 개선하기
<script>
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
} else {
$('.form-select').eq(1).addClass('form-hide');
}
});
</script>
(응용 3) 이벤트 리스너 안에서 e.currentTarget, this 사용하기
<script>
$('.form-select').eq(0).on('input', function(e){
var value = e.currentTarget.value; // 또는 var value = this.value;
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
} else {
$('.form-select').eq(1).addClass('form-hide');
}
});
</script>
위에서 작성한 코드는 확장성이 부족하다.
셔츠 사이즈를 95, 100이라고 하드코딩 해 놓고 보여 주기만 하기 때문이다. 실체 쇼핑몰이라면 셔츠 사이즈가 자주 바뀔 텐데, 이럴 경우 서버에서 보낸 데이터 갯수에 맞게 <option> 태그를 생성해 줘야 좋을 것이다.
그래서 자바스크립트로 html을 생성하는 방법을 알아보자.
HTML 생성하는 법 1
<div> 안에 <p> 태그를 생성하려면 아래와 같이 코드를 짜면 된다.
- document.createElement()를 쓰면 html 자료를 하나 생성해 준다.
- 편의에 맞게 조작한 다음 appendChild()를 사용해서 필요한 곳에 넣으면 html이 생성된다.
<div id="test">
</div>
<script>
var a = document.createElement('p');
a.innerHTML = '안녕';
document.querySelector('#test').appendChild(a);
</script>
HTML 생성하는 법 2
- 문자 자료로 html을 만든 다음, insertAdjacentHTML() 안에 넣는다.
- 'beforeend'는 안쪽 맨 하단에 추가하라는 뜻이다. (다른 걸로 변경 가능)
<div id="test">
</div>
<script>
var a = '<p>안녕</p>';
document.querySelector('#test').insertAdjacentHTML('beforeend', a);
</script>
1번 방법은 코드가 길고 복잡하기 때문에 특별한 이유가 없으면 2번 방법을 사용한다. (1번이 더 빠르게 동작하지만 0.0000x초 차이다.)
(+) jQuery에서는 아래와 같이 작성하면 된다. append는 안쪽 맨 하단에 추가하라는 뜻이다.
<div id="test">
</div>
<script>
var a = '<p>안녕</p>';
$('#test').append(a);
</script>
(+) 안쪽에 추가하는 것이 아니라 아예 바꾸고 싶다면?
- div를 찾아서 innerHTML = '<p></p>'를 쓰면 된다.
- jQuery에서는 .html()이다.
<div id="test">
<h4>반가워</h4>
</div>
<script>
var a = '<p>안녕</p>';
$('#test').html(a);
</script>
Q. 사용자가 바지를 선택하면 하단에 다른 사이즈를 선택할 수 있는 <select> 박스가 나타나게 하려면?
<form class="container my-5 form-group">
<p>상품선택</p>
<select class="form-select mt-2">
<option>모자</option>
<option>셔츠</option>
<option>바지</option> // 추가
</select>
<select class="form-select mt-2 form-hide">
<option>95</option>
<option>100</option>
</select>
</form>
첫번째 <select> 에 바지 옵션을 추가한다. 바지 옵션을 선택하면 28, 30 사이즈가 담긴 <select>가 떠야 한다.
html을 미리 만들어 뒀다가 보여 줘도 되지만, 실제 쇼핑몰의 경우라면 그렇게 만들어 놓을 수는 없다. (바지 사이즈가 매일 바뀐다면 매일 html을 수정해야 한다...) 실제 서비스는 매번 서버에서 데이터를 받아와서 "데이터 개수만큼 <option> 생성해라"라고 코드를 짜 놓는다.
<script>
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
var size = `<option>28</option><option>30</option>`;
$('.form-select').eq(1).append(size);
}
});
</script>
▲ 그래서 사용자가 바지를 선택하면
1. 두번째 <select> 보여 주기
2. 두번째 <select> 안을 비우기
3. html 만들어서 두번째 <select> 안에 appen 해라
라고 코드를 작성하면 된다.
(응용) 바지를 눌렀다가 다시 셔츠를 누르면 두번째 <select>에 셔츠 사이즈가 뜨게 해 보자.
<script>
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
var size = `<option>95</option><option>100</option>`;
$('.form-select').eq(1).append(size);
}
else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
var size = `<option>28</option><option>30</option>`;
$('.form-select').eq(1).append(size);
}
});
</script>
- 셔츠 눌렀을 때 두번째 <select> 안에 있는 html도 조정해 줘야 한다.
이번에는 서버에서 바지 사이즈 데이터를 가져와서 그 개수만큼 <option>을 생성해 보자.
<script>
var pants = [28, 30, 32];
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
// 여기에 어떤 코드를 작성해야 함
}
});
</script>
▲ 맨 위에 pants라는 변수를 하나 만들어 서버에서 보낸 데이터라고 가정해 보자.
pants 데이터 개수만큼 <option>을 생성하고 싶으면 어떻게 해야 할까?
<script>
var pants = [28, 30, 32];
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
for (let i = 0; i < pants.length; i++){
<option>생성해주세요~
}
}
});
</script>
▲ 반복문을 사용하면 된다. pants.length만큼 반복해 달라고 하면 된다.
그런데 for문보다 조금 더 쉬운 반복문을 알아보자.
forEach 반복문
- array 자료 뒤에 붙일 수 있는 forEach()라는 반복문인 기본 함수가 있다.
var pants = [28, 30, 32];
pants.forEach(function(){
console.log('안녕')
});
▲ pants 안의 데이터 개수만큼 forEach 콜백함수 안에 있는 코드가 실행 된다.
실행해 보면 콘솔창에 '안녕'이 3번 출력된다.
그래서 array 자료를 다룰 때 for 반복문 대신 forEach를 뒤에 붙여도 된다.
var pants = [28, 30, 32];
pants.forEach(function(a, i){
console.log(a)
});
ㄹ 콜백함수 안에 파라미터 2개까지 작명이 가능한데
첫번째 파라미터는 반복문 돌 때마다 array안에 있던 하나하나의 데이터,
두번째 파라미터는 반복문 돌 때마다 0부터 1씩 증가하는 정수가 된다.
<script>
var pants = [28, 30, 32];
$('.form-select').eq(0).on('input', function(){
var value = $('.form-select').eq(0).val();
if (value == '셔츠') {
$('.form-select').eq(1).removeClass('form-hide');
}
else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
pants.forEach(function(a){
$('.form-select').eq(1).append(`<option>${a}</option>`);
// 또는 $('.form-select').eq(1).append('<option>' + a + '</option>');
})
}
});
</script>
▲ 그래서 위의 코드도 이렇게 바꾸면 된다.
이제 pants라는 서버에서 보낸 데이터가 바뀔 때마다 거기에 맞게 <option>이 생성된다. 변화에 대응이 좋은 코드가 되었다.
<script>
var pants = [28, 30, 32, 34];
var shirts = [95, 100, 105];
$('.form-select').eq(0).on('input', function(e){
var value = this.value;
if( value == '셔츠'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
shirts.forEach(function(a){
$('.form-select').eq(1).append('<option>'+a+'</option>');
})
} else if (value == '바지'){
$('.form-select').eq(1).removeClass('form-hide');
$('.form-select').eq(1).html('');
pants.forEach((a, i) => {
$('.form-select').eq(1).append('<option>'+a+'</option>');
});
} else {
$('.form-select').eq(1).addClass('form-hide');
}
});
</script>
▲ 셔츠의 경우도 작성해 보았다.
object 자료 다룰 때 for in 반복문
- object 자료 개수만큼 반복문을 돌리고 싶다면 for in 반복문을 사용하면 된다.
var obj = { name : 'kim', age : 20 }
for (var key in obj){
console.log('안녕')
}
▲ 콘솔창에 '안녕'이 2회 출력된다.
- for in 반복문을 쓰면 object 자료 안에 있는 key와 value를 다 출력할 수 있다.
- key라고 작명하는 부분은 반복문이 돌 때마다 object 자료 안에 있던 key 값이 된다.
var obj = { name : 'kim', age : 20 }
for (var key in obj){
console.log(key)
}
▲ 콘솔창에 name, age가 출력된다.
- 실제 자료인 value를 출력하고 싶으면 console.log(obj[key])를 출력하면 된다.
var obj = {name : 'kim', age: 20}
for (var key in obj){
console.log(obj[key]);
}
▲ 콘솔창에 kim, 20이 출력된다.
반복문의 용도
1. 코드를 복붙하고 싶으면
2. array, object 자료 다 꺼내고 싶을 때 반복문을 사용하면 유용하다.
arrow function 문법
- 함수를 만드는 다른 문법이 있는데, 특히 콜백함수를 만들 때 자주 쓰는 방법이다.
var pants = [28, 30, 32];
pants.forEach(function(a){
console.log(a)
});
pants.forEach((a) => {
console.log(a)
});
- function 키워드 대신 => 화살표를 () 우측에 부착해도 함수를 만들 수 있다.
- 이것을 arrow function, 화살표 함수라고 한다.
pants.forEach( a => {
console.log(this)
});
- arrow function은 파라미터가 하나면 () 소괄호를 생략해도 된다.
- 함수 중괄호 안에 return 한 줄 밖에 없으면 { } 중괄호와 return 동시에 생략해도 된다.
- 간결해서 콜백함수에 자주 사용하는 사람들이 있다.
let 함수 = function(){ console.log('안녕') }
let 함수 = () => { console.log('안녕') }
- 참고로 위와 같이 함수를 만들어 쓰는 사람도 있다. 이럴 때에도 arrow function이 가끔 보인다.
일반 함수와 arrow fucntion의 기능 차이가 하나 있는데,
함수 안에서 this를 써야 할 경우
- 일반 함수는 함수 안에서 this를 알맞게 재정의해 준다.
- arrow function은 함수 안에서 this를 재정의해 주지 않고 바깥에 있던 this를 그대로 사용한다.
그래서 이벤트 리스너 콜백함수 안에서 this를 써야 하면 arrow function는 의도와 다르게 동작할 수 있다.
* 이 포스팅은 코딩애플 강의를 토대로 작성하였습니다.