※ Keep in mind
본 내용은 웹개발과정의 강의 중 내용을 복습을 위해서 메모한 것에 불과한 것입니다. 이러한 연유로 강의내용을 오인한 나머지 오기재 및 불기재가 있을 수 있으니 '참고'만 해주시길 바랍니다. 저의 경우에도 본 내용을 단순히 읽은 것이 결코 저의 것이라고 생각하지 않습니다. 본 내용은 복습을 위한 초기 내지 중간 과정에 불과한 것이고, 이후에 내용을 보충 후 인출 및 설명하기 과정이 있어야 비로소 복습의 단추가 어느 정도 마무리되어간다고 볼 수 있습니다.
따라서 당초에 본 내용은 비공개였습니다. 그럼에도 불구하고 본 내용을 공개한 점은 함께 공부하는 동료들과 나눔을 바탕으로 배움과 성장의 공진화라는 소기의 목적을 달성에 어느 정도 도움이 될 수 있기 때문이라고 생각합니다.
I. Aajx
1. 목록 추가 제거
(1) 목록을 지우는 방법 1
while(menuList.firstElementChild){
menuList.firstElementChild.remove;
}
반복문을 이용해서 엘리먼트를 지워나가는 방식이 있다.
(2) 목록을 지우는 방법 2
//기존목록을 지우고 목록을 지우는 방법2
//menuList.textContent = "<span style ='color:blue'>test hello</span>";
//menuList.innerText = "<span style ='color:blue'>test hello</span>";
//menuList.innerHTML = "<span style ='color:blue'>test hello</span>";
menuList.innerHTML = "";
이 방식은 기존 menulist 노드에다가 새로운 태그들을 대입해서 없애주는 방식이야
textContent 는 우측 HTML을 단순히 텍스트로 입력받는거야
innerText 는 우측 HTML은 태그안 컨텐트를 입력받는거야
innerHTML은 우측 HTML태그와 컨텐트 모두 입력받는거야
(3) 목록을 만들어 채우기
1) 방법 1 : DOM객체를 직접 생성해서 채우기
//menuList.textContent = "<span style ='color:blue'>test hello</span>";
//menuList.innerText = "<span style ='color:blue'>test hello</span>";
//menuList.innerHTML = "<span style ='color:blue'>test hello</span>";
menuList.innerHTML = "";
let menuSection = document.createElement("section");
menuList.className = "menu";
let form = document.createElement("form");
form.className = ""; //왜 ""?
menuSection.append(form);
menuList.append(menuSection);
목록을 지우거나 새롭게 대입하는 방법으로 요소의 내용들을 없앨 수 있다.
section 태그로 요소를 만들어서 menusection 에다가 넣는다
그리고 menuList.className 에다가 menu라는 클래스 속성 값을 설정한다.
마찬가지로 form 태그로 요소를 만들어서 form 에다가 넣는다
그리고 menuList.className 에는 공백으로 넣는다.
section 과 form 을 새롭게 넣어서 가능해
append를 해서 새롭게 만들 수 있어
이 버전은 구형방식이야! 쓰기는 하지만 너무 노가다야
사람들은 이것을 피하고 싶어서 어떻게든 문자열을 이용해서 해!
2)
방법2 : 템플릿(``)문자열을 이용한
menuList.innerHTML = "";
//목록을 만들어 채우기
//방법1 : DOM객체를 직접 생성해서 채우기
let menuSection = document.createElement("section");
menuList.className = "menu";
let form = document.createElement("from");
form.className = ""; //왜 ""?
// menuSection.appendChild(form); //노드 인터페스 이용한 방법
menuSection.append(form);// 엘레먼트 인터페이스 이용방법
menuList.append(menuSection);
//방법2 : 문자열을 이용한 객체생성
let template =`
<div class="menu-list">
<section class="menu">
<form class="">
<h1>${menus[0].name}/<span>(커피)</span></h1>
<div class="menu-img-box">
<a href="detail"><img class="menu-img" src="/image/product/12.png"></a>
</div>
<div class="menu-price">4500 원</div>
<div class="menu-option-list">
<span class="menu-option">
<input class="menu-option-input" type="checkbox">
<label>ICED</label>
</span>
<span class="menu-option ml-2">
<input class="menu-option-input" type="checkbox">
<label>Large</label>
</span>
</div>
<div class="menu-button-list">
<input class="btn btn-fill btn-size-1 btn-size-1-lg" type="submit" value="담기">
<input class="btn btn-line btn-size-1 btn-size-1-lg ml-1" type="submit" value="주문하기">
</div>
</form>
</section>
</div>`;
menuList.innerHTML = template;
template를 선언해서 innerHTML로 객체생성을 가능해!
문자열방식이야
이 경우 thymeleaf 없이 ${menus[0].name} 으로
각 내용에 따라 이름이 다르게 나와!
이렇게 하면 잘하면... 망할수있어!
3)
다른 메뉴들도 다 출력하고싶으면 반복문을 써야해!
for(let menu of menus){
let template =`
<section class="menu">
<form class="">
<h1>${menus[0].name}/<span>(커피)</span></h1>
<div class="menu-img-box">
<a href="detail"><img class="menu-img" src="/image/product/12.png"></a>
</div>
<div class="menu-price">4500 원</div>
<div class="menu-option-list">
<span class="menu-option">
<input class="menu-option-input" type="checkbox">
<label>ICED</label>
</span>
<span class="menu-option ml-2">
<input class="menu-option-input" type="checkbox">
<label>Large</label>
</span>
</div>
<div class="menu-button-list">
<input class="btn btn-fill btn-size-1 btn-size-1-lg" type="submit" value="담기">
<input class="btn btn-line btn-size-1 btn-size-1-lg ml-1" type="submit" value="주문하기">
</div>
</form>
</section>`;
menuList.innerHTML += template;
}
이렇게 하면 반복문으로 모두 출력이 가능해
그런데 단 하나 때문에 문제가 생길 수있어
아래쪽에 복합연산자 (+=) 는 치명적일수 있어!
문자열이 점점 누적되면서 대입하는데, 문자열을 누적연산하는거도 큰 overhead발생해
왜냐하면 여기다가 대입할 때마다 기존것 다 없애고 다시 만들고 하는방식이야!
O(n^4)이상 으로 문제가 생겨
4)
이런방식을 방지하기 위해서 이거를 써
for(let menu of menus){
let template =`
<section class="menu">
<form class="">
<h1>${menu.name}/<span>(커피)</span></h1>
<div class="menu-img-box">
<a href="detail"><img class="menu-img" src="/image/product/12.png"></a>
</div>
<div class="menu-price">4500 원</div>
<div class="menu-option-list">
<span class="menu-option">
<input class="menu-option-input" type="checkbox">
<label>ICED</label>
</span>
<span class="menu-option ml-2">
<input class="menu-option-input" type="checkbox">
<label>Large</label>
</span>
</div>
<div class="menu-button-list">
<input class="btn btn-fill btn-size-1 btn-size-1-lg" type="submit" value="담기">
<input class="btn btn-line btn-size-1 btn-size-1-lg ml-1" type="submit" value="주문하기">
</div>
</form>
</section>`;
// menuList.innerHTML += template;
menuList.insertAdjacentHTML("beforeend",template);
}
insertAdjacentHTML 를 이용하면 붙이기가 가능하다
이 DOM메소드는 공통점은 HTML,XML특정 텍스트는 파싱하지만 이미사용중인 요소는 다시 파싱하지 않아!
element.insertAdjacentHTML(position, text);
이렇게 사용이 가능한거야!
이경우 인자 넣는곳 위치에 따라 다른데 beforeend를 하면 끝나기 직전에 추가로 더 붙이는거야
뭐를? template 을!
2. 카테고리 표시
1)
카테고리 이름에 클릭한 것에 대해서 바뀌게끔 해야해!
기존것 남겨두고 추가하는 방식으로 가능해!
let el = (tagName === 'LI')? e.target : e.target.parentNode;
el.classList.add("menu-selected");
이 방식으로 해서 el 의 클래스에다가 기존 것은 남겨두고 붙이는거야! (클래스 값을 추가)
그런데 활성화는 됐는데 원래대로 돌아가지가 않아!
선택 안된 요소 중에 찾아서 지우기 보다! 선택된 애만 활성화 시키는 방법으로 해보자!
같은 녀석이 있는지 확인해서 그 여부로 넣을지가 가능해
지우는건 반복문으로 하지말고 기존에 된 놈들 중에 클래스를 보고 셀렉해서 없애면돼
그리고 기존의 것이 있는지는 현재 것에서 찾아보면 돼
if(tagName != 'LI' && tagName != 'A') //li 가 아니면 return;
return; //두가지 조건 만족시 본 함수에서 나가게해서 못쓰게 해
let el = (tagName === 'LI')? e.target : e.target.parentNode;
let curLi = ul.querySelector("li.menu-selected");
if(curLi !== el){
curLi.classList.remove("menu-selected");
el.classList.add("menu-selected");
}
이 부분은 본 셀렉터가 있을 때 대입된다. 대입이 되었다는 것은 곧 해당 버튼부분의 색이 바뀌었다는 의미이다.
조건을 넣어서 현재 li와 클릭한 li를 비교(menu-selected 동일여부)해서 다르면
현재것 제거하고, 클릭한 것에다가 class를 추가해주면 돼!
다만 이 경우 굳이 이렇게 할 필요없이 함수를 나가게 해도 충분해!
if(tagName != 'LI' && tagName != 'A') //li 가 아니면 return;
return; //두가지 조건 만족시 본 함수에서 나가게해서 못쓰게 해
let el = (tagName === 'LI')? e.target : e.target.parentNode;
let curLi = ul.querySelector("li.menu-selected");
if(curLi === el){
return;
}
curLi.classList.remove("menu-selected");
el.classList.add("menu-selected");
현재 버튼과 클릭 것이 같으면 특별히 클래스를 제거하거나, 추가할 필요없이 함수를 return 시켜서 아래 코드들이 작동안하게 하면 돼!
3. 검색
1)
이제 요청도구가 달라졌어
이제는 JS로 요청하는거야 검색버튼을 누르면 실행(onclick)되는것을 불러오는게 필요해
const form = document.querySelector(".search-header form");
const findbutton = form.querySelector(".icon-find");
console.log(form);
findbutton.onclick = function(e){
console.log(e);
}
우선 form 과 findbutton을 받아오자
받아온 것에 대해서 클릭이 되는 콜백함수를 만들어서 하자
비단 클릭말고 모든 과정은 콘솔을 띄어보면서 테스트!!!
findbutton.onclick = function(e){
e.preventDefault();
console.log(e);
}
preventDefault() 를 띄우면 계속해서 볼 수있어!
태그마다 기능이있는것과 없는것이 있어 스크립트가 얘(검색버튼)를 이용하면 서버로 전송하는 html 태그가 있어
태그가 가진 행위를 "디폴트" 행위야
디폴트 행위를 막는 함수야 즉 기본행위가 있으면 기본기능을 막자는거야 (prevent)
2)
검색을 하기위해서는 검색한 것을 가져와야해
이것을 가져와야하는데 미리뽑아놓을지 아니면 클릭했을 때 가져올지 선택해야해
기왕이면 클릭했을 때 뽑아내는게 좋아
<방법>
findbutton.onclick = function(e){
e.preventDefault();
const queryInput = form.querySelector("input[name=q]");
console.log(queryInput.value);
}
input의 데이터 중 name이 q 인 것을 queryInput에다가 담아줄수있어
담아준것을 value 하면은 콘솔로 출력이 가능해
3)
button 클릭 했을 때에도 새롭게 api를 요청하는 방식을 이해해보자
findbutton.onclick = function(e){
e.preventDefault();
const queryInput = form.querySelector("input[name=q]");
console.log(queryInput.value);
let query = queryInput.value;
const request = new XMLHttpRequest();
request.onload = function(){
let menus = JSON.parse(request.responseText)
console.log(menus);
}
request.open("GET", `http://localhost:8080/menus?q=${query}`,true); //브라우저에서 url을 입력하는것과 같은 요
request.send(); //
}
입력받은 값을 query 에 담고 api get 할 때 보내자!
이와 관련된 부분에 대해서 콘솔로 출력이 성공했다. onlad 때! log에 찍어줌
4)
데이터를 화면에 바인딩하는 작업을 함수화 시켜주자!
//bind를 추가해주는거야!
// list를 받아서 출력해주는 함수
function bind(menus){
//기존 목록을 모두 지우고
//menuList.children[0].remove;
//기존목록을 지우고 목록을 지우는 방법1
//while(menuList.removeChild(menuList.firstElementChild)){
//menuList.removeChild(menuList.firstElementChild);
//}
//menuList.replaceChildren();
//기존목록을 지우고 목록을 지우는 방법2
//menuList.textContent = "<span style ='color:blue'>test hello</span>";
//menuList.innerText = "<span style ='color:blue'>test hello</span>";
//menuList.innerHTML = "<span style ='color:blue'>test hello</span>";
menuList.innerHTML = "";
//목록을 만들어 채우기
//방법1 : DOM객체를 직접 생성해서 채우기
// let menuSection = document.createElement("section");
// menuList.className = "menu";
//
// let form = document.createElement("from");
// form.className = ""; //왜 ""?
//
//// menuSection.appendChild(form); //노드 인터페스 이용한 방법
// menuSection.append(form);// 엘레먼트 인터페이스 이용방법
// menuList.append(menuSection);
//방법2 : 문자열을 이용한 객체생성
for(let menu of menus){
let template =`
<section class="menu">
<form class="">
<h1>${menu.name}/<span>(커피)</span></h1>
<div class="menu-img-box">
<a href="detail"><img class="menu-img" src="/image/product/${menu.img}"></a>
</div>
<div class="menu-price">4500 원</div>
<div class="menu-option-list">
<span class="menu-option">
<input class="menu-option-input" type="checkbox">
<label>ICED</label>
</span>
<span class="menu-option ml-2">
<input class="menu-option-input" type="checkbox">
<label>Large</label>
</span>
</div>
<div class="menu-button-list">
<input class="btn btn-fill btn-size-1 btn-size-1-lg" type="submit" value="담기">
<input class="btn btn-line btn-size-1 btn-size-1-lg ml-1" type="submit" value="주문하기">
</div>
</form>
</section>`;
// menuList.innerHTML += template;
menuList.insertAdjacentHTML("beforeend",template);
}
}
화면에 출력해주는 부분의 반복을 줄이기 위해서 떼내고 출력해준다.
findbutton.onclick = function(e){
e.preventDefault();
const queryInput = form.querySelector("input[name=q]");
console.log(queryInput.value);
let query = queryInput.value;
const request = new XMLHttpRequest();
request.onload = function(){
let menus = JSON.parse(request.responseText)
console.log(menus);
bind(menus);
}
request.open("GET", `http://localhost:8080/menus?q=${query}`,true); //브라우저에서 url을 입력하는것과 같은 요
request.send(); //
}
검색하기에서도 bind(menus) 로 출력을하고
let categoryId = el.dataset.cid;
const request = new XMLHttpRequest();
request.onload = function(){
let menus = JSON.parse(request.responseText)
bind(menus);
};
request.open("GET", `http://localhost:8080/menus?c=${categoryId}`,true); //브라우저에서 url을 입력하는것과 같은 요
request.send(); //
카테고리로 하는것에도 마찬가지이다.
5)
js로 하면 검색도 빠르고 좋아! 요청하는 쿼리내용이 보이지않기 때문에 url도 깔끔하게 정리가 될 수 있어
다만 나말고 다른사람도 그대로 보게 해주기 위해서는 query 가 그대로 남아있어야해!
dom은 js가 살아있게하는 기반이야! dom은 브라우저에 살아있는 윈도우 객체야
사용자 입력 즉 마우스 키보드 입력을 하기 때문에 그림이나 그래프 출력이가능해! dom으로 입출력이 가능해 JS로!
우리는 DOM기반으로 만들고있어
이전에는 직접 안썻어 제이쿼리로 썻었어! 왜냐 옛날에는 DOM이 아니라 DO(모델링X) 였어 각자 달랐어
노드 삭제하기 위해서 조건문 넣어서 브라우저 마다 달리해야했어 그래서 Jquery가 나왔어
dom안쓰려고 제이쿼리 쓰는거야 그래서 굳이 쓸 필요없어
DOM안쓰는방법은 MVC프레임웍이였어
이전에는 DOM각자라서 문제인데, 이제는 직접안쓰고자 문제야
최근에는 랭귤러,뷰 등 으로 조작을 해
<DOM 중요요소>
1. 노드 생성,수정,삭제 여부 (노드조작)
2. 이벤트 처리여부
3. 휠, 키보드, 드래그드랍,페이지로드
(순서 3 -> 2 -> 1)
dom을 아예안쓰는게 좋은거야! vuw를 써보자
II. Vue
1. vue의 시작점인 Angular JS의 탄생이유
(1) 들어가며
이제 DOM직접 안쓰려고 해서 그래! 너무 low한 내용 다루는거 같아! 마치 스프링 속을 보는 느낌이야!
생산성때문에 DOM을 직접쓰면 혼나
앵귤러 부터 프레임웍을 알아볼 필요가 있어
구글이 선도주자야
페이지 하나로 다 진행한다고 해서 SPA를 만들었어
(2) Google의 Feedback 프로젝트
모달을 자주 띄우는데, 구글페이지 특성상 JS 많이 사용돼
(3) JS로 만드는 윈도우 프로그래밍
1)
화면 띄우는게 가장 많은 부분을 처리해
2)
Miško HEVERY
구글의 프로젝트에서 17000라인인데 대부분이 DOM조작이야
라이브러를 만들어서 1500라인으로 줄였어
3)
앵귤러는 생산성위해서 MVW패턴을 적용할 라이브러리로 만들어져
MS에서는 오래전부터 이용되어왔어
MVW에서 W는 whatever야!
4)
dom 프로그래밍고 MVW차이
계산기에서 DOM 제거 하면 이거만 남아
우리는 바인딩되어있는 변수만 신경쓰면돼! DOM은 쓰지않아!
5)
앵귤러 몰락이유?
1. 보충
2. 회고
1) 생각할수록 나에게는 프론트가 더 맞는거 아닌가 싶기도하다!
몇일전에 내가 재미를 봤던 부분도 타임리프에서 데이터를 보내주고 그 결과를 눈으로 확인할 때인데, 사실 그부분도 MVC에서 view이다
이것은 CSR에서는 프론엔드인데,,,, 생각이 든다.
'배움 __IL > TIL 1기' 카테고리의 다른 글
TIL : 80번째- 230330 [3-4-목] (0) | 2023.03.30 |
---|---|
TIL : 79번째- 230329 [3-4-수] (0) | 2023.03.29 |
TIL : 77번째- 230327 [3-4-월] (0) | 2023.03.27 |
TIL : 76번째- 230324 [3-3-금] (0) | 2023.03.24 |
TIL : 75번째- 230323 [3-3-목] (0) | 2023.03.23 |