ㅁ 동적으로 요소를 생성하거나 복제, 제거한다
ㅁ < 동적으로 요소 생성 >
(1) 문자열로 요소 만드는 방식
- 변수 = '<b>안녕하세요</b>' // 이렇게 만들고 변수에 담을 수 있다는 뜻.
(2) jQuery 객체로 요소 만드는 방식
- 변수 = $('<b></b>').text('안녕하세요');
- 변수 = $('<b>안녕하세요</b>'); // 더 간단한 방법 ( b태그 요소 객체가 만들어짐)
- jQuery 객체로 요소를 만들면 jQuery 메소드를 사용할 수 있다.
문자열을 달러 괄호로 감싸면 된다.
- 이때까지 달러 괄호 안에 요소 선택을 위해 선택자를 써왔는데, 항상 선택자를 써야하는 것은 아니다.
요소를 생성할 때는 문자열을 쓴다.
- 어떤 태그의 요소를 만들고 싶은지 그 태그를 작성해야 한다.
ㅁ < 동적으로 만들어진 요소를 특정 영역에 추가 >
(1) 문자열로 만들어진 요소를 추가
요소.html('문자열로생성한요소');
(2) jQuery 객체로 만들어진 요소를 추가
- 아래의 두 방법 중 편한 방식을 택해서 쓰면 된다.
- jQuery 객체가 동적으로 만들어진 요소 객체다.
이렇게 만든 객체를 어떤 요소 내에 추가를 할건지 요소를 제시한다.
- jQuery객체.appendTo(요소) : 요소 내에 마지막 자손으로 jQuery 객체가 추가된다.
- jQuery객체.prependTo(요소) : 요소 내에 첫번째 자손으로 jQuery 객체가 추가된다.
- jQuery객체.insertBefore(요소) : 요소의 앞에 이전 형제로 추가 (동등 레벨)
- jQuery객체.insertAfter(요소) : 요소의 뒤에 다음 형제로 추가
- 요소.append(jQuery객체) : 요소 내에 마지막 자손으로 jQuery 객체가 추가된다.
- 요소.prepend(jQuery객체) : 요소 내에 첫번째 자손으로 jQuery 객체가 추가된다.
- 요소.before(jQuery객체) : 요소의 앞에 이전 형제로 추가
- 요소.after(jQuery객체) : 요소의 뒤에 다음 형제로 추가
<!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>
.added {
color : palegreen;
}
</style>
</head>
<body>
<h2>요소생성</h2>
<h1 id="test1">
<span>A</span>
</h1>
<h1 id="test2">
<span>A</span>
</h1>
<h1 id="test3">
<span>A</span>
</h1>
<h1 id="test4">
<span>A</span>
</h1>
<script>
</script>
</body>
</html>
- 기본세팅. h1 요소 내에 span 요소가 자손으로 있다.
h1 요소 내에 또다른 span 요소를 추가해 볼 예정이다.
그리고 동적으로 만들어진 요소에 '.added'라는 클래스를 부여해서 글씨 색깔을 바꿀 예정이다.
<!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>
.added {
color : palegreen;
}
</style>
</head>
<body>
<h2>요소생성</h2>
<h1 id="test1">
<span>A</span>
</h1>
<h1 id="test2">
<span>A</span>
</h1>
<h1 id="test3">
<span>A</span>
</h1>
<h1 id="test4">
<span>A</span>
</h1>
<script>
$(document).ready(function() {
$('<span class="added">B</span>').appendTo('#test1');
})
</script>
</body>
</html>
- span 요소를 jQuery 객체로 만들고, id가 test1인 h1 요소 내의 마지막 자손으로 추가했다.
- span은 인라인 요소다. div는 블럭 요소.
블럭요소는 전체 가로 너비 차지. 인라인 요소는 내용의 크기만큼 너비 차지.
<!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>
.added {
color : palegreen;
}
</style>
</head>
<body>
<h2>요소생성</h2>
<h1 id="test1">
<span>A</span>
</h1>
<h1 id="test2">
<span>A</span>
</h1>
<h1 id="test3">
<span>A</span>
</h1>
<h1 id="test4">
<span>A</span>
</h1>
<script>
$(document).ready(function() {
$('<span class="added">B</span>').appendTo('#test1');
$('<span class="added">B</span>').prependTo('#test2');
$('<span class="added">B</span>').insertBefore('#test3');
$('<span class="added">B</span>').insertAfter('#test4');
})
</script>
</body>
</html>
- B가 작게보여진다. h1 요소 내에 추가된 게아니고. h1과 동위선상으로 이전/이후 위치에 추가되었기 때문에 글씨 크기는 크지 않다. h1 요소 내에 있지 않기 때문이다.
ㅁ jQuery와 요소의 위치를 바꿔본다. (다른 메소드 사용)
<!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>
.added {
color : palegreen;
}
</style>
</head>
<body>
<h2>요소생성</h2>
<h1 id="test1">
<span>A</span>
</h1>
<h1 id="test2">
<span>A</span>
</h1>
<h1 id="test3">
<span>A</span>
</h1>
<h1 id="test4">
<span>A</span>
</h1>
<script>
$(document).ready(function() {
/*
$('<span class="added">B</span>').appendTo('#test1');
$('<span class="added">B</span>').prependTo('#test2');
$('<span class="added">B</span>').insertBefore('#test3');
$('<span class="added">B</span>').insertAfter('#test4');
*/
$('#test1').append($('<span class="added">B</span>'));
$('#test2').prepend($('<span class="added">B</span>'));
$('#test3').before($('<span class="added">B</span>'));
$('#test4').after($('<span class="added">B</span>'));
})
</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 방식으로 연결하는 방법 -->
<style>
.item {
background-color: blueviolet;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
margin: 10px;
font-size: 25px;
color: white;
font-weight: 900;
}
</style>
</head>
<body>
<h2>요소 복제</h2>
<div id="clone-test">
<div id="item1" class="item"> <!-- 복제할 요소 -->
<span>안녕</span>
</div>
</div>
<button id="clone-btn">복제</button>
<!-- 복제한 요소를 붙여넣기 할 영역 -->
<div id="clone-result"></div>
<script>
</script>
</body>
</html>
- 기본 세팅
- 문구를 수직정렬하고 싶다면 line-height를 height 값과 동일하게 주면 된다.
ㅁ < 요소 객체 복제 메소드 >
요소.clone( [true|false] ) : 해당 요소를 복제해서 반환
true : 복제할 요소의 이벤트도 같이 복사
false : 복제할 요소의 이벤트는 복사 안 함 (기본값)
<!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>
.item {
background-color: blueviolet;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
margin: 10px;
font-size: 25px;
color: white;
font-weight: 900;
}
</style>
</head>
<body>
<h2>요소 복제</h2>
<div id="clone-test">
<div id="item1" class="item"> <!-- 복제할 요소 -->
<span>안녕</span>
</div>
</div>
<button id="clone-btn">복제</button>
<!-- 복제한 요소를 붙여넣기 할 영역 -->
<div id="clone-result"></div>
<script>
$(function() {
// 이벤트도 복제되는지 확인 위해 복제할 요소에 이벤트 부여하기
$('.item').hover(function(){ // 두 function 제시. 첫번째는 mouseenter시, 두번째는 mouseout시.
$(this).css('backgroundColor', 'pink');
}, function(){
$(this).css('backgroundColor', 'green');
})
// 복제 버튼 실행시 실행되게
$('#clone-btn').on('click', function() {
// id가 item1인 요소를 복제해서 #clone-result에 자손으로 추가할 것이다.
$('#clone-result').append($('#item1'));
// 그런데 이렇게 하면 기존 요소는 사라짐. 아예 이동되어버린다.
})
})
</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 방식으로 연결하는 방법 -->
<style>
.item {
background-color: blueviolet;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
margin: 10px;
font-size: 25px;
color: white;
font-weight: 900;
}
</style>
</head>
<body>
<h2>요소 복제</h2>
<div id="clone-test">
<div id="item1" class="item"> <!-- 복제할 요소 -->
<span>안녕</span>
</div>
</div>
<button id="clone-btn">복제</button>
<!-- 복제한 요소를 붙여넣기 할 영역 -->
<div id="clone-result"></div>
<script>
$(function() {
// 복제할 요소에 이벤트 부여하기
$('.item').hover(function(){
$(this).css('backgroundColor', 'pink');
}, function(){
$(this).css('backgroundColor', 'green');
})
// 복제 버튼 실행시 실행되게
$('#clone-btn').on('click', function() {
// id가 item1인 요소를 복제해서 #clone-result에 자손으로 추가
// $('#clone-result').append($('#item1'));
// 그런데 이렇게 하면 기존 요소는 사라짐. 아예 이동되어버린다.
$('#clone-result').append($('#item1').clone()); // 복붙은 됐으나 이벤트는 복사 안 됨.
$('#clone-result').append($('#item1').clone(true)); // 이벤트까지 복사되었다.
})
})
</script>
</body>
</html>
- 복제된 요소를 지금은 바로 append로 추가하고 있지만 변수에 기록을 해놨다가 활용해도 된다.
ㅁ < 하위 요소 제거 메소드 >
- 요소.empty() : 해당 요소의 하위 요소들 제거
ㅁ < 선택 요소 제거 및 잘라내기 메소드 >
- 둘 다 호출만으로 선택된 요소가 제거된다.
제거할 뿐만 아니라 제거된 요소 자체를 반환해준다.( =이게 잘라내기 기능이다)
- 요소.remove() : 해당 요소 제거 후 반환 (이벤트는 같이 반환 안됨)
- 요소.detach() : 해당 요소 제거 후 반환 (이벤트도 같이 반환)
ㅁ < 요소 제거 및 잘라내기 >
<!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>
.item {
background-color: blueviolet;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
margin: 10px;
font-size: 25px;
color: white;
font-weight: 900;
}
</style>
</head>
<body>
<h2>요소 제거 및 잘라내기</h2>
<div id="remove-test">
<div id="item2" class="item"> <!-- 제거할 요소 -->
<span>안녕</span>
</div>
</div>
<button id="empty-btn">제거</button>
<button id="remove-btn">잘라내기1</button>
<button id="detach-btn">잘라내기2</button>
<!-- 잘라낸 요소를 붙여넣기 할 영역 -->
<div id="remove-result"></div>
<script>
$(function() {
// 제거할 요소에 이벤트 부여하기 (이전거 그대로 재탕. 제거할 요소에도 이벤트가 연결되어있다.)
$('.item').hover(function(){
$(this).css('backgroundColor', 'pink');
}, function(){
$(this).css('backgroundColor', 'green');
})
})
</script>
</body>
</html>
- 기본 세팅.
- hover 이벤트도 그대로다.
<!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>
.item {
background-color: blueviolet;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
margin: 10px;
font-size: 25px;
color: white;
font-weight: 900;
}
</style>
</head>
<body>
<h2>요소 제거 및 잘라내기</h2>
<div id="remove-test">
<div id="item2" class="item"> <!-- 제거할 요소 -->
<span>안녕</span>
</div>
</div>
<button id="empty-btn">제거</button>
<button id="remove-btn">잘라내기1</button>
<button id="detach-btn">잘라내기2</button>
<!-- 잘라낸 요소를 붙여넣기 할 영역 -->
<div id="remove-result"></div>
<script>
$(function() {
// 제거할 요소에 이벤트 부여하기 (이전거 그대로 재탕. 제거할 요소에도 이벤트가 연결되어있다.)
$('.item').hover(function(){
$(this).css('backgroundColor', 'pink');
}, function(){
$(this).css('backgroundColor', 'green');
})
$('#empty-btn').on('click', function() {
// $('#item2').empty(); 이거는 버튼 누르면 박스 자체가 사라지는게 아니고 '안녕' 텍스트만 사라짐.
$('#remove-test').empty();
})
$('#remove-btn').on('click', function() {
// $('#item2').remove(); 이렇게만 쓰면 버튼을 누르는 순간 박스 자체가 사라지고 끝.
const removeEl = $('#item2').remove();
$('#remove-result').append(removeEl); // 붙여넣기 되었으나 이벤트는 없다.
})
$('#detach-btn').on('click', function() {
// $('#item2').detach();
const detachEl = $('#item2').detach();
$('#remove-result').append(detachEl); // 이벤트도 이동되었다.
})
})
</script>
</body>
</html>
- remove()와 detach()는 제거된 요소 자체를 반환하기 때문에 변수에 담아뒀다가 어딘가에 출력도 가능하다.
ㅁ 연습문제.
문제1.
#create-btn 버튼 클릭시 위의 객체배열의 값으로 테이블 요소를 생성해서 #result 영역에 출력하기.
이때 3행 3열짜리 테이블로 만든다.
첫번째 열에는 상품명, 두번째 열에는 상품 가격, 세번째 열에는 해당 상품에 대한 정보를 볼 수 있는 '확인' 버튼 두기.
(이게 제목행에 들어갈 내용은 아님. 제목행 없음)
'확인' 버튼을 클릭하면 alert로 각각의 행의 상품명 : name, 상품가격 : 30000 나오게끔.
문제2.
동적으로 만들어진 테이블 요소 내의 각 행별 마지막 셀에 있는 버튼 클릭시 해당 행의 상품정보(상품명, 상품가격)를 alert로 띄워주기.
<!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>연습</h2>
<button id="create-btn">요소 생성</button>
<br><br>
<div id="result"></div>
<script>
$(document).ready(function() {
const productList = [ // 세 개의 상품 객체가 있는 배열
{
name : '마우스',
price : 10000
},
{
name : '키보드',
price : 20000
},
{
name : '마이크',
price : 30000
}
];
})
</script>
</body>
</html>
- 동적으로 요소를 만들어서 어딘가에 출력하고자 한다면 그 영역을 선택할 수 있게끔 적어도 요소 하나는 있어야만 한다.
아이디가 result인 div 요소 하나를 생성한다. 그리고 여기에 동적으로 생성된 요소를 추가한다.
- 페이지 로드 시에는 아무것도 없지만 버튼을 누르는 순간 요소를 동적으로 만들어서 #result에 자손으로 추가한다.
<!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>연습</h2>
<button id="create-btn">요소 생성</button>
<br><br>
<div id="result"></div>
<script>
$(document).ready(function() {
const productList = [
{
name: '마우스',
price: 10000
},
{
name: '키보드',
price: 20000
},
{
name: '마이크',
price: 30000
}
];
$('#create-btn').on('click', function() {
let tableEl = '<table border="1">';
for(let product of productList){
tableEl += '<tr>'
+ '<td>' + product.name + '</td>'
+ '<td>' + product.price + '</td>'
+ '<td><button>확인</button></td>'
+ '</tr>';
}
tableEl += '</table>';
$('#result').html(tableEl);
})
// $('#result button') 이렇게 하면 안 됨. 페이지 로드 시에는 버튼이 없다.
$('#result').on('click', 'button', function() { // 하위 요소에 이벤트 걸기
// $(this) : 현재 이벤트가 발생한 클릭된 확인 버튼
// $(this).parent().prev().prev() : 현재 클릭된 확인 버튼 행의 첫번째 셀
// $(this).parent().prev() : 현재 클릭된 확인 버튼 행의 두번째 셀
alert('상품명: ' + $(this).parent().prev().prev().text()
+ ', 상품가격: ' + $(this).parent().prev().text());
})
})
</script>
</body>
</html>
- button이 td 안에 있기 대문에 parent().prev().prev()다.
- 문제2처럼 할 때가 굉장히 많다.
동적으로 요소가 만들어지고 그 만들어진 행에 각각의 버튼에 이벤트를 연결해야할 때가 많다.
사이트의 댓글 기능. 댓글을 작성하는 순간 하단에 내가 작성한 댓글이 보여진다. 이게 동적으로 만들어진 요소다.
- 그 행에 댓글 수정버튼, 삭제버튼이 있는데 그런게 다 동적으로 만들어진 요소라서 거기에 이벤트를 연결하고자 한다면 문제1처럼 매개변수 3개짜리 on 메소드를 사용.
그리고 그때 각각 클릭시 현재 이벤트가 발생한 요소로부터 탐색해야될 때 문제2처럼 쓰고.(parent().prev().prev())
- this를 쓸 수 있는 이유는 익명함수이기 때문.
화살표함수를 쓸 때는 이벤트 객체를 매개변수로 전달받아서 evt.target으로 사용해야한다.
ㅁ 짤막 문제 - 자바스크립트 구문을 jQuery식으로 바꾸기