ㅁ each 메소드
- 배열의 요소들 또는 객체의 속성들을 순회할때 사용할 수 있는 메소드
- for in 문과 유사하게 수행됨. (반복문 느낌)
- 사용법
(1) $.each( 배열 | 객체, function(매개변수1, 매개변수2) {
순회하면서 수행할 내용
})
(2) $(배열).each(function(매개변수1, 매개변수2) {
순회하면서 수행할 내용
})
- 배열이나 객체의 속성을 순회하면서 매번 function이 실행됨. (즉 콜백함수같은 거다)
- 배열제시시 첫번째 인자값으로 인덱스 수, 두번째 인자값으로 (인덱스 자리에 있는) 요소가 전달됨.
(dom 요소 아니고 배열에 있는 요소)
- 객체제시시 첫번째 인자값으로 속성명, 두번째 인자값으로 속성값이 전달됨.
(객체는 인덱스의 개념이 없음. 속성명과 속성값으로 구성되어있다)
- 함수가 자동으로 실행이될 때 매번 두개씩 값을 전달받는다.
- 매개변수 사용하지 않을 거면 안써도 됨. 두번째 매개변수는 안 받고 첫번째 매개변수만 받아도 됨.
- jQuery에서 제공하는 메소드여서 순수 자바스크립트 방식의 배열을 $를 써서 jQuery 객체로 변환해야 each메소드를 사용할 수 있다.
ㅁ 배열
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<script>
$(document).ready(function() {
const arr = ['가', '나', '다', '라']; // 길이4의 문자열들이 존재하는 자바스크립트 배열.
// (1) for in 문 이용
for(let index in arr) {
console.log('인덱스: ' + index + ', 값: ' + arr[index]);
}
// for in 문을 사용해서 순회할 수도 있지만 jQuery 라이브러리를 쓰고 있다면 each라는 메소드를 사용해서 배열을 순회할 수도 있다.
// 똑같은 배열을 each 메소드로 순회해본다.
// each 메소드는 2가지 유형이 있다.
// (2) each 메소드 이용 1
$.each(arr, function(index, value) {
console.log('인덱스: ' + index + ', 값: ' + value); // for in 문과 결과는 동일하다.
})
// (3) each 메소드 이용 2
$(arr).each(function(index, value) {
console.log('인덱스: ' + index + ', 값: ' + value); // for in 문과 결과는 동일하다.
})
})
</script>
</body>
</html>
ㅁ 객체
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<script>
$(document).ready(function() {
const student = {
name: '시로',
age: 20,
addr: '서울'
};
// 객체는 인덱스의 개념이 없어서 일반적인 for 반복문은 안 되고, for in문만 가능하다. 배열은 3개 다 가능.
// 1) for in문 이용
for(let prop in student) { // 속성명을 '문자열'로 반환한다. 'name', 'age', 'addr'
console.log('속성명: ' + prop + ', 속성값: ' + student[prop]);
}
// for in문을 쓸 때는 .으로 접근하면 안 되고 대괄호 표기법으로 접근해야 한다.
// prop 자체가 문자열이라 대괄호 안에 prop 쓰고 따옴표는 안 써도 된다.
// student.prop 하면 정말로 prop이란 속성이 객체에 있는지를 찾는다.
// 2) each 메소드 이용
$.each(student, function(prop, value){
console.log('속성명: ' + prop + ', 속성값: ' + value);
})
})
</script>
</body>
</html>
ㅁ 예제1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<button id="btn1">학생조회</button> <br><br>
<!-- 버튼을 클릭하는 순간 db로부터 데이터를 조회(select)해올 수 있다.
그걸 보통 AJAX라는 기능을 이용해서 할 때가 있는데
그때는 DB로부터 조회된 데이터를 자바스크립트 측에서 코드로 전달받는다.
그때 객체 배열의 형태를 많이 본다.
그걸 이제 화면에 동적으로 요소를 만들어서 뿌릴 수 있어야 한다 -->
<table id="student-list" border="1">
<thead>
<th>순번</th>
<th>이름</th>
<th>나이</th>
<th>주소</th>
<th>정보확인</th>
</thead>
<tbody>
</tbody>
</table>
<script>
$(document).ready(function() { // 혹시 모르니까 요소 다 만들어진 후에 제대로 선택이 되게끔 이걸 작성함.
$('#btn1').on('click', function() {
// ★ 이 구문 안에서 AJAX 이용해서 db로부터 데이터 조회 가능.
// db로부터 다음과 같이 조회되었다는 가정하에 아래와 같은 배열의 형태로 돌아옴.
// db로부터 jdbc과정을 통해서 조회한 arraylist 데이터가 자바스크립트 측으로 오면 이런 객체 배열의 형태다.
const students = [{name: '연초봄', age: 20, addr: '서울'},
{name: '금사향', age: 30, addr: '부산'},
{name: '이춘향', age: 25, addr: '서울'}]
let result = '';
// for문 써도 됨. jQuery 기능을 쓰고 있다면 each 메소드를 써도 되고.
$.each(students, function(index, stu) { // 2번째 인자값으로 객체 자체가 전달된다.
result += '<tr>'
+ '<td>' + (index + 1) + '</td>'
+ '<td>' + stu.name + '</td>'
+ '<td>' + stu.age + '</td>'
+ '<td>' + stu.addr + '</td>'
+ '<th><button>확인</button></th>' // th 셀로 줘서 가운데 정렬시키기
+ '</tr>';
})
$('#student-list tbody').html(result); // 버튼을 클릭하면 동적으로 요소가 만들어진다.
})
})
</script>
</body>
</html>
- ★ 이 구문 안에서 AJAX 이용해서 db로부터 데이터 조회 가능.
db로부터 다음과 같이 조회되었다는 가정하에 아래와 같은 배열의 형태로 돌아옴.
각각의 학생 객체들은 VO 객체에 담겨 온다. 여러 학생 객체니까 arraylist 에 담겨있다.
arraylist 데이터를 자바스크립트 측으로 반환받으면 제이슨으로 전송이 된다.
자바에서의 arraylist가 자바스크립트에서는 다음과 같이 배열이다.
자바에서의 vo 객체 하나가 자바스크립트에서는 중괄호 객체 하나다.
- '학생조회' 버튼을 누르면 동적으로 테이블의 행들이 생성된다.
db로부터 데이터를 조회해와서 동적으로 요소를 만들어가지고 tbody에 tr들을 추가할 수 있어야 한다.
- 테이블을 만들때 바로 tr로 만들기보다 사실 thead, tbody 이렇게 구조를 나눠주는 것이 제일 좋습니다.
그래야 thead 내에 있는 행들에 별도의 이벤트, tbody에 있는 행들에 별도의 이벤트를 따로따로 걸 수 있다.
ㅁ 예제 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<button id="btn1">학생조회</button>
<br><br>
<table id="student-list" border="1">
<thead>
<th>순번</th>
<th>이름</th>
<th>나이</th>
<th>주소</th>
<th>정보확인</th>
</thead>
<tbody>
</tbody>
</table>
<script>
$(document).ready(function() {
$('#btn1').on('click', function() {
// AJAX 이용해서 db로부터 데이터 조회 가능.
// db로부터 다음과 같이 조회되었다는 가정하에 아래와 같은 배열의 형태로 돌아옴.
const students = [{name: '연초봄', age: 20, addr: '서울'},
{name: '금사향', age: 30, addr: '부산'},
{name: '이춘향', age: 25, addr: '서울'}]
let result = '';
$.each(students, function(index, stu) { // 2번째 인자값으로 객체 자체가 전달된다.
result += '<tr>'
+ '<td>' + (index + 1) + '</td>'
+ '<td>' + stu.name + '</td>'
+ '<td>' + stu.age + '</td>'
+ '<td>' + stu.addr + '</td>'
+ '<th><button>확인</button></th>' // th 셀로 줘서 가운데 정렬시키기
+ '</tr>';
})
$('#student-list tbody').html(result); // 버튼을 클릭하면 동적으로 요소가 만들어진다.
})
/*
문제1.
학생 정보가 보여지는 행(tr) 클릭시
해당 행의 배경색을 lightgray 색상으로 적용
*/
$('#student-list tbody').on('click', 'tr', function() { // 페이지 로드시에는 tbody 안에 tr이 없다.
$(this).css('backgroundColor', 'lightgray');
})
/*
문제2.
각 행별 확인 버튼 클릭시
alert로 해당 행의 학생의 정보 출력하시오.
단, 문제1에 의해서 해당 행의 배경색이 변경되어서는 안 됨.
*/
$('#student-list tbody').on('click', 'button', function(evt) { // 버튼이 동적으로 만들어진 요소라 바로 선택할 수 없다.
// $(this).parent.parent를 쓰는 대신 $(this).parents()하면 모든 상위 요소가 선택된다. document까지 싹 다.
// $('this').parents('tr')하면 버튼이 존재하는 행만을 선택함.
// 자주 쓸 예정이라 변수에 담는다.
const $trEl = $(this).parents('tr'); // 보통 jQuery 방식으로 선택한 요소객체를 변수에 담을 때는 $를 붙여준다.
// 여기서의 this = evt.target
// $trEl.children()하면 모든 셀들이 다 선택된다.
$trEl.children().eq(1) // 2번째 셀
$trEl.children().eq(2)
$trEl.children().eq(3)
// name, age, addr이 있는 셀에다가 클래스를 부여해서 가져올 수도 있다.
// $trEl.find('.name')
// $trEl.find('.age')
// $trEl.find('.addr')
alert('이름: ' + $trEl.children().eq(1).text() + '\n'
+ '나이: ' + $trEl.children().eq(2).text() + '\n'
+ '주소: ' + $trEl.children().eq(3).text() );
// tr 요소의 하위 요소로 button이 있기 때문에 button에 대한 이벤트가 tr에도 전파된다.
// 버튼을 클릭시에는 해당 행의 배경색을 바꾸고 싶지 않다면 이벤트 전파를 막는 메소드 사용.
// 하위요소 이벤트객체.stopPropagation() 실행
evt.stopPropagation();
})
})
</script>
</body>
</html>
- 보통 jQuery 방식으로 선택한 요소객체를 변수에 담을 때는 변수명에 $를 붙여준다.
- (문제1) 토글기능을 넣고 싶다면 아래와 같이 클래스를 만들고 hasClass를 이용한다.
- (문제2) 반복문에 클래스 부여하기
- 하위요소의 이벤트를 상위 요소 클릭시에도 안나오게 할 뿐 아니라, 상위 요소 이벤트가 그 하위 요소에 영향을 미치지 않게도 하나 봄.
- 기본적으로 하위요소 클릭시 상위요소 이벤트까지 실행되는 이벤트 버블링 발생.
하위요소 클릭시 하위요소의 이벤트만 작동하고 상위요소의 이벤트는 실행하고 싶지 않으면(전파방지하고자 할 경우)
하위요소 이벤트객체.stopPropagation() 실행
ㅁ 예제3
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
<style>
.bg-0{background-color: red;}
.bg-1{background-color: blue;}
.bg-2{background-color: violet;}
.bg-3{background-color: green;}
.bg-4{background-color: purple;}
</style>
</head>
<body>
<h2>each 메소드</h2>
<button id="btn2">클릭</button>
<div id="item-list">
<h3>item-1</h3>
<h3>item-2</h3>
<h3>item-3</h3>
<h3>item-4</h3>
<h3>item-5</h3>
</div>
<script>
$(document).ready(function() {
$('#btn2').on('click', function() {
// $('#item-list h3').css('backgroundColor', 'blue'); 이렇게 하면 일괄적으로 부여.
// h3 요소들에 순차적으로 접근하면서 각기 다른 bg-* 클래스 부여.
$('#item-list h3').each(function(index, h3El) {
// (1) 자바스크립트 방식 - 클래스 관련 property
// h3El.className = 'bg-' + index;
// (2) jQuery 방식
// $(h3El).addClass('bg-' + index);
// (3) 매개변수 활용 없이 this로 순차적으로 접근되는 요소 사용 가능. (화살표함수에선 this 쓰지 마시고)
// each 메소드의 콜백함수 에서의 this는 순차적으로 접근되는 요소다. (h3 - 자바스크립트 방식 객체다.)
// each 메소드 바깥에서의 this는 클릭 이벤트가 발생하는 button 요소다.
// this.className = 'bg-' + index; 자바스크립트방식
$(this).addClass('bg-' + index); // jQuery 방식
})
})
})
</script>
</body>
</html>
- $('#item-list h3') 이거 for문 못 쓴다. jQuery 방식으로 선택한 요소 객체는 each메소드로 순차적으로 접근해야 한다. (??)
ㅁ 예제4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<button id="btn3">클릭</button>
<div id="test-list">
<h3 class="test">test1</h3>
<h3>test2</h3>
<h3 class="test">test3</h3>
<h3 class="test">test4</h3>
<h3>test5</h3>
<h3 class="test">test6</h3>
</div>
<script>
$(document).ready(function() {
$('#btn3').on('click', function() {
// h3 요소들 중
// 클래스로 test를 가지고 있을 경우 배경색을 orange, 가지고 있지 않으면 yellow로 부여.
})
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- (1) 파일 다운받아서 연결하는 방법
<script src="../assets/assets/lib/jquery-3.7.1.min.js"></script> -->
<!-- (2) CDN 방식으로 연결하는 방법 -->
</head>
<body>
<h2>each 메소드</h2>
<button id="btn3">클릭</button>
<div id="test-list">
<h3 class="test">test1</h3>
<h3>test2</h3>
<h3 class="test">test3</h3>
<h3 class="test">test4</h3>
<h3>test5</h3>
<h3 class="test">test6</h3>
</div>
<script>
$(document).ready(function() {
$('#btn3').on('click', function() {
// h3 요소들 중
// 클래스로 test를 가지고 있을 경우 배경색을 orange, 가지고 있지 않으면 yellow로 부여.
/* 내방식. 잘 됨. 근데 each문을 안 썼음
$('#test-list h3').filter('.test').css('backgroundColor', 'orange');
$('#test-list h3').not('.test').css('backgroundColor', 'yellow');
*/
$('#test-list h3').each(function() {
// if( $(this).hasClass('test') ) { 이것도 되고
if( $(this).is('.test') ) { // is(선택자)로 요소가 선택자에 만족하는지 비교도 가능.
$(this).css('backgroundColor', 'orange');
}
else {
$(this).css('backgroundColor', 'yellow');
}
})
})
})
</script>
</body>
</html>