«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
Recent Posts
Recent Comments
관리 메뉴

뉴히의 개발 로그

[TIL] 20230530 - 클로저 closure / if문 alert창 한번만 띄우기 / 키보드 enter키로 검색 클릭 본문

개발일지/TIL

[TIL] 20230530 - 클로저 closure / if문 alert창 한번만 띄우기 / 키보드 enter키로 검색 클릭

뉴히 2023. 5. 30. 21:14

 

 클로저 closure 

  • 클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합니다
// 카운트 상태 변경 함수 #3
const increase = (function () {
    // 카운트 상태 변수
    let num = 0;
  
    // 클로저
    return function () {
      return ++num;
    };
  })();
  
  // 이전 상태값을 유지
  console.log(increase()); //1
  console.log(increase()); //2
  console.log(increase()); //3

1. 위 코드가 실행되면, '즉시 실행 함수'가 호출 -> 함수가 반환(inner) -> increase에 할당
  (function () {
    // 카운트 상태 변수
    let num = 0;
  
    // 클로저
    return function () {
      return ++num;
    };
  })

함수가 이렇게 할당된다고 보면됨!

2. increase변수에 할당된 함수는 자신이 정의돈 위치에 의해서 결정된 사우이 스코프인 즉시 실행 함수의 '렉시컬 환경'을 기억하는 클로저다 

-> let num =0; 을 기억한다고 생각하면됨! 
3. 즉시 실행함수는 -> 즉시 소멸! (outer 함수가 불리자마자 바로 call stack에서 popup 되는 것과 비슷 !!)
[결론] : num은 초기화가 안됨! 외부에서 접근할 수 없는 은닉된 값! 의도되지 않은 변경도 걱정할 필요가 없다 ->num은 increase에서만 변경할 수있기 때문에 

 

보면 이해는 되지만 아직 제대로 개념이 잡히지 않아서 좀더 다시 봐야겠다!

 

 if문 alert 한번만 띄우기!  

개인 프로젝트에서 해당 검색 키워드가 들어간 제목의 영화들만 리스팅해주는 부분을 구현중이었는데

검색 제목이 없을 경우 alert을 띄워주는 기능을 추가하려했다!

그런데...?

확인 버튼 누르면 계속 뱅뱅뱅뱅 돌더라는 ㅎㅎㅎ 

input에 들어간 검색 키워드가 없으니 계속 돌면서 alert창을 띄우기 때문인듯!!

 

문제의코드!

if(titleLower.includes(inputValue)){
    temp_html +=`<div class="card-list" id="${_id}">
                    <img src="https://image.tmdb.org/t/p/original${poster}" class="card-img" />
                    <div class="card-info">
                        <h5 class="card-title">${title}</h5>
                        <p class="card-text">${overview}</p>
                        <p class="card-avg">${vote_avg}</p>
                    </div>
                </div>`       
    cardWrap.innerHTML = temp_html;
} else {
    alert("검색한 영화가 없습니다! 다시 검색해 주세요.");
}

그래서 찾아보니 alert창을 한번띄우고 다른 페이지로 넘어가게 

location을 써서 넘기면 된다고 했는데!!

if(titleLower.includes(inputValue)){
    temp_html +=`<div class="card-list" id="${_id}">
                    <img src="https://image.tmdb.org/t/p/original${poster}" class="card-img" />
                    <div class="card-info">
                        <h5 class="card-title">${title}</h5>
                        <p class="card-text">${overview}</p>
                        <p class="card-avg">${vote_avg}</p>
                    </div>
                </div>`       
    cardWrap.innerHTML = temp_html;
} else {
    alert("검색한 영화가 없습니다! 다시 검색해 주세요.");
    window.location.href="index.html";  
}

안됨!!!!

그래서 그럼 조건을 한번 걸어줘볼까? 해서 if문을 추가하니까 무사히 창이 닫히더라는!

if(titleLower.includes(inputValue)){
    temp_html +=`<div class="card-list" id="${_id}">
                    <img src="https://image.tmdb.org/t/p/original${poster}" class="card-img" />
                    <div class="card-info">
                        <h5 class="card-title">${title}</h5>
                        <p class="card-text">${overview}</p>
                        <p class="card-avg">${vote_avg}</p>
                    </div>
                </div>`       
    cardWrap.innerHTML = temp_html;
} else {
    alert("검색한 영화가 없습니다! 다시 검색해 주세요.");
    if(window.confirm(message) === true){
        window.location.href="index.html";  
    }                                      
}

 검색시 키보드 enter키로 클릭가능 

HTML

<div class="search">
    <label for="검색창" class="blind">검색창</label>
    <input type="text" id="search-input" name="search" placeholder="검색어 입력"/>
    <button type="submit" id="search-btn" class="search-btn" onclick="">검색</button>
</div>

JS

document.getElementById("search-input").addEventListener("keyup", function(e) {
    if (e.keyCode === 13) {
        document.getElementById("search-btn").click();
    }
});

이렇게 짧은 코드로 구현이 가능!

그런데 참고로 keyCode 속성은 더 이상 권장되지 않기때문에 KeyboardEvent.code 대신에

document.getElementById("search-input").addEventListener("keyup", function(e) {
    if (e.code === 'Enter') {
        document.getElementById("search-btn").click();
    }
});

이렇게 사용하길 !!!