- 검색 함수
- Jquery로 배열 다루기 : each();
- 정적 바인딩, 동적 바인딩
선택자만 있으면 대상 요소를 확실하게 선택할 수 있다. 그러나 앞으로 경험할 문제 상황에선 선택자를 사용하지 못하는 경우가 분명 존재한다. 이 경우 우리가 아는 요소의 주소를 기준으로 다른 요소의 주소를 검색해야 한다.
<div id="home">
Home
<div id="grand_parent">
GrandParent
<div id="parent01">
Parent01
<div id="brother01">
Brother01
</div>
<div id="me">
Me
<div id="sister01">
Sister01
<div id="baby">
Baby01
</div>
</div>
<div id="sister02">
Sister02
</div>
</div>
<div id="brother02">
Brother02
</div>
</div>
<div id="parent02">
Parent02
</div>
</div>
</div>
$("#me").children(); me 태그의 직계자손만 검색하여 반환
$("#me").children()[0]; // == div#sister01
단, 반환된 배열에서 요소를 뽑으면, 해당 요소는 제이쿼리 노드가 아닌 자바스크립트 객체라서 제이쿼리 기능을 사용할 수 없다.
물론 제이쿼리 객체인 $(“#sister01”)
와 같은 요소를 가리키는 것은 맞다. 하지만 제이쿼리 기능을 사용하기 위해선 $()
으로 다시 감싸주거나 $("#me").children("#sister01")
처럼 아예 id값으로 지정해서 출력해야 한다.
$("#me").find("#sister01");
$("#me").find("#sister02");
$("#me").find("#baby");
$("#me").siblings();
$("#me").siblings("#brother02");
$("#me").parent();
$("#me").parent(“#parent01”);
$("#me").closest("#grand_parent");
$("#me").closest(); // 적용 안됨
$("#me").closest(“#parent02”); // 적용 안됨
기존에 자바스크립트에서 배열의 요소를 다룰 때는 다음과 같이 getElementsByClassName("box");
함수를 사용했다.
해당 함수 사용시 대상 요소들에서 추출한 값을 배열로 반환해주며, 이를 반복문으로 꺼내서 사용한다.
<div class="box">box1</div>
<div class="box">box2</div>
<div class="box">box3</div>
<div class="box">box4</div>
<div class="box">box5</div>
<script>
// js방식으로 배열 뽑기
let boxArr = document.getElementsByClassName("box");
for(let i =0; i<boxArr.length; i++){
console.log(boxArr[i]);
};
이는 제이쿼리로도 똑같이 구현이 된다.
let boxArr = $(".box"); // 제이쿼리 노드
for (let i = 0; i < boxArr.length; i++) {
console.log(boxArr[0].innerHTML);
}
단, 제이쿼리 배열에서 요소를 추출하면 해당 요소는 제이쿼리 노드가 아닌 자바스크립트 객체이다. 그러니 주의해서 사용해야 한다.
이제 본론으로 돌아와서, 제이쿼리의 반복문인 each()
를 알아보자.
<div class="box">box1</div>
<div class="box">box2</div>
<div class="box">box3</div>
<script>
$(".box").each(function(index, item){
console.log(index);
console.log(item);
});
</script>
each()
는 콜백 패턴을 이용한 반복문으로, 위 예시에서 선택자로 선택된 요소들을 모두 끌어온다. 그 후 요소의 순서를 index에 요소 그 자체를 item에 담고 이를 $(item)
으로 응용해서 써먹을 수 있다.
그 후, 한 객체씩 가지고 와서 안에 정의된 코드를 실행하고 반환하는 반복작업을 마지막 객체까지 진행한다.
each()
로 반복작업을 할 수 있다. (콜백 패턴을 이용한다)$()
으로 감싼 뒤, 제이쿼리로 사용할 수 있다.return false
를 주면 반복을 멈춘다.여러 개의 요소에 이벤트 처리를 하기 위해서는 바인딩 기법을 사용해야 한다. 단, 해당 요소가 정적 요소인지, 동적 요소인지에 따라서 다른 바인딩 처리를 해줘야 한다. 먼저 정적 요소에 대한 바인딩 처리를 해보자.
자바스크립트에서 여러 요소를 긁어오면, 배열 상태로 반환하기 때문에 각 요소를 사용하려면 다음과 같이 반복문으로 추출과 동시에 이벤트 처리한다.
<button class="btn">button1</button>
<button class="btn">button2</button>
<button class="btn">button3</button>
<button class="btn">button4</button>
<button class="btn">button5</button>
<script>
let arr = document.getElementsByClassName("btn");
// 반복문으로 각 객체마다 이벤트 처리
for(let i = 0; i<arr.length; i++){
arr[i].onclick = function(){
alert(arr[i].innerHTML);
}
};
</script>
반면 제이쿼리는 똑같이 배열로 묶어두지만, 위의 과정을 자동으로 처리해준다. 단, 각 객체를 구분하기 위해서 this
를 사용한다.
$(".btn").on("click", function () {
alert(this.innerHTML);
});
여기서 this
는 이벤트가 감지된, 또는 발생한 해당 객체 자체를 가리킨다. 즉, 클릭 시 alert
가 실행되는 것을 .btn
을 가진 요소들에 모두 부여했지만, 각 요소를 구별하지 못해 내부의 텍스트를 가져올 수 없다.
따라서 이벤트가 발생한 해당 소스를 지목하기 위해 this
를 쓰며, 이는 자바스크립트 객체가 되므로 $()
로 감싸서 사용한다. (배열에 빼냈다)
하지만 정적 바인딩은 다음과 같이 로딩 이후, 생성되는 객체에 대해서는 부여되지 않는다.
// 동적 요소
let record = $(“<tr>”);
record.append($("<td>").HTML(“<button>O</button>”));
$(“table”).append(record); // table은 정적요소
위 예시의 요소들을 <script>
내부에서 특정 조건에 따라 생성되는 동적인 요소로서, 해당 요소들은 조건 충족으로 생성되기 이전까지는 존재하지 않는다.
즉, 정적 바인딩을 하게 되면 첫 로딩에 브라우저는 HTML을 쭉 읽으면서 정적 요소들에 이벤트 처리를 해뒀고, 이때 존재하지 않은 동적 요소들은 이벤트 처리가 되지 않았다. 따라서 동적 요소는 동적 바인딩이란 이벤트 처리가 필요하다.
제이쿼리에서 동적 바인딩은 정적 바인딩과 크게 다르지 않다. 대신 두 가지 조건만 채워주면 된다.
let record = $(“<tr>”);
record.append($("<td>").HTML(“<button class=“btn”>O</button>”));
$(“table”).append(record); // table은 정적요소
$(“table”).on(“click”, “.btn” function(){
alert(this.innerHTML);
});
이런 이벤트를 가진 버튼을 만들고 이 버튼을 추가해라 가 되는거죠
위 예시에선 table
요소에 내부에서 .btn
이라는 동적 요소가 생성되면, 위 코드에 의해 .btn
값의 버튼에는 click 시 alert(this.innerHTML);
라는 이벤트가 부여된다.
즉, 정적 요소(table) 내부에 동적 요소(.btn)에는 이벤트 발생 시(click) 해당 기능을 하도록 이벤트 처리해라.
또한, 대상이 될 부모 요소는 구조상 상위 요소면 어떤 요소에도 걸어둘 수 있다. (document, body)
this
를 사용한다.this
는 이벤트가 발생한 해당 리소스를 가리킨다.[ 피드백 ]
$()
으로 감싸줘야한다.