webucks project_220222
저번 로그인 페이지에서 로그인하면 넘어오게 되는 그 페이지입니다.

총 12장의 이미지가 들어있는 갤러리입니다.
- 커피 사진과 이름은 모두 다르게 해주세요.
 - 반응형을 고려하지 않으셔도 괜찮습니다.
 
- 반응형을 고려하신다면 커피 리스트는 flex-wrap 혹은 grid를 활용해주세요.
 - 커피 이미지에 마우스를 호버했을 때 이미지를 확대해주세요.
 
사실 위의 조건들은 css단계에서 처리 가능한 기능이라서 크게 어렵지 않아요.
제가 어려웠던건..
사진 12개를 일일이 html로 작성하기 귀찮은데, 이걸 어떻게 자바스크립트로 처리할 방법 없을까?
였습니다.
리스트 html 생성
- 커피의 종류별로 객체를 생성한다. 커피의 데이터는 이미지경로와 이름으로 구성되어 있다.
 
- ex) 콜드 브루 커피=
 {name:'나이트로 바닐라 크림',imgUrl:'/img/cb-01.jpg'}
브루드 커피={name:'아이스 커피',imgUrl:'/img/b-01.jpg'}- 객체의 이름과 이미지 경로를 각각 읽어와
 <ul>의 하위 태그로 구성한다.
- 갤러리 1개의 HTML 구조
 <section class="coffee-section cold-brew"> <h3 class="coffee-section-title">콜드 브루 커피 ☕</h3> <ul class="coffee-gall"> <!--여기부터--> <li> <a class="coffee-thumbnail" href="#"> <div class="coffee-img"><img src="img/cb-01.jpg" alt="cb-01"/></div> <p class="coffee-name">커피이름</p> </a> </li> <!--여기까지 생성할 부분--> </ul> </section>
const coldBrewList = [{
    name: '나이트로 바닐라 크림',
    imgUrl: 'img/cb-01.jpg'
}, {
    name: '나이트로 콜드 브루',
    imgUrl: 'img/cb-02.jpg'
}, {
    name: '돌체 콜드 브루',
    imgUrl: 'img/cb-03.jpg'
}, {
    name: '바닐라 크림 콜드 브루',
    imgUrl: 'img/cb-04.jpg'
}, {
    name: '벨벳 다크 모카 나이트로',
    imgUrl: 'img/cb-05.jpg'
}, {
    name: '시그니처 더 블랙 콜드 브루',
    imgUrl: 'img/cb-06.jpg'
}, {
    name: '제주 비자림 콜드 브루',
    imgUrl: 'img/cb-07.jpg'
}, {
    name: '콜드 브루',
    imgUrl: 'img/cb-08.jpg'
}, {
    name: '콜드 브루 몰트',
    imgUrl: 'img/cb-09.jpg'
}, {
    name: '콜드 브루 오트 라떼',
    imgUrl: 'img/cb-10.jpg'
}]
const brewedList = [{
    name: '아이스 커피',
    imgUrl: 'img/b-01.jpg'
}, {
    name: '오늘의 커피',
    imgUrl: 'img/b-02.jpg'
}]
이렇게 배열로 한번 감싸고 안에 객체 여러개를 넣었습니다.
const coldBrewGall = document.querySelector('.cold-brew .coffee-gall'),
    brewedGall = document.querySelector('.brewed .coffee-gall');
그리고 태그가 들어갈 곳인 각각의 갤러리 ul태그를 변수로 지정해줍니다.
return 명령문은 값을 하나만 반환할 수 있습니다.
마음만으로는 객체 내의 이름과 url을 한꺼번에 뽑아내고 싶은데 return의 특성때문에 이름 따로, url 따로 뽑아내기로 했어요.
function exportName(data) {
    let coffeeName = [];
    for (let key in data) {
        coffeeName.push(data[key]['name']);
    }
    return coffeeName;
}
function exportUrl(data) {
    let coffeeImg = [];
    for (let key in data) {
        coffeeImg.push(data[key]['imgUrl']);
    }
    return coffeeImg;
}
파라미터 data에 위에서 지정해준 객체 coldBrewList,brewedList가 들어갈거에요.
이제 저기서 객체들을 차례로 확인하면서 key값인 name과 imgUrl들의 value를 뽑아내 배열로 반환합니다.
function addCoffeeList(obj, gallery) {
    let nameIndex = exportName(obj);
    let imgIndex = exportUrl(obj);
    
    for (let i = 0; i < obj.length; i++) {
      
    }
};
addCoffeeList(coldBrewList, coldBrewGall);
addCoffeeList(brewedList, brewedGall);
함수 addCoffeeList은 파라미터로 객체 이름과 출력해낼 갤러리 이름을 받아낼겁니다.
마음만으로는 위쪽에서 반환된 coffeeName과 coffeeImg 변수를 그대로 가져오고 싶습니다. 그런데 저 변수들은 exportName 내에서만 활용이 가능한 변수라서 또 변수를 지정해뒀어요.
이제 변수 nameIndex와 imgIndex가 그 자리를 대신합니다.
그리고 객체의 데이터 개수만큼 for문이 작동할텐데, 저렇게 다중 구조의 HTML을 삽입하려면 어떻게 해야할까요? 그래서 찾아봤습니다.
function function1() {
  var ul = document.getElementById("list");
  var li = document.createElement("li");//변수 li는 <li>태그
  li.appendChild(document.createTextNode("Four"));//<li>태그 내에 'Four'이라는 텍스트 삽입, <li>Four</li>로 만들어짐
  ul.appendChild(li);//이런 li가 ul 하위에 추가됨
}
와~createElement로 태그를 하나하나 만들어준 다음 createTextNode로 데이터를 넣고appendChild를 쓰면 되는군요~
되겠냐고
<li>
    <a class="coffee-thumbnail" href="#">
       <div class="coffee-img"><img src="img/cb-01.jpg" alt="cb-01"/></div>
       <p class="coffee-name">커피이름</p>
    </a>
</li>
저는 li 밑에 a가 있고 또 그 안에 div와 p가 있는 복잡한걸 만들고... 거기에 클래스랑 url까지 줄거라니까요?
일단 더이상 생각하기 싫어서, 변수 자체를 이렇게 만들어 줍니다.
function addCoffeeList(obj, gallery) {
    let nameIndex = exportName(obj);
    let imgIndex = exportUrl(obj);
    
    for (let i = 0; i < obj.length; i++) {
        let listTag = `<li><a class="coffee-thumbnail" href="#">
        <div class="coffee-img">
        <img src="${imgIndex[i]}" alt="${imgIndex[i].substr(4,imgIndex[i].length)}"/>
        </div><p class="coffee-name">${nameIndex[i]}</p></a></li>`      
    }
};
src에는 i번째 데이터의 이미지 경로가 들어갈테고, alt값에는 이미지 경로에서 /img/만 제외한 cb-01.jpg형식의 텍스트가 들어갈 예정입니다.
.coffee-name안에는 i번째nameIndex인 이름값이 들어가고..
하지만 이러한 태그를 아무리 HTML에 넣으려 해봤자,
appendChild(listTag): 실패
append(listTag): 실패
어쩌라는 걸까요? 슬퍼진 저는 이렇게 생성된 li태그를 배열에 담아둔 후 무작정 태그들을 집어넣기로 했습니다.
 function addCoffeeList(obj, gallery) {
    let nameIndex = exportName(obj);
    let imgIndex = exportUrl(obj);
    let tagArray = [];
   
    for (let i = 0; i < obj.length; i++) {
        let listTag = `<li><a class="coffee-thumbnail" href="#">
        <div class="coffee-img">
        <img src="${imgIndex[i]}" alt="${imgIndex[i].substr(4,imgIndex[i].length)}"/>
        </div><p class="coffee-name">${nameIndex[i]}</p></a></li>`
        
        tagArray.push(listTag);
    }
};
이제 배열 tagArray에 담긴 열 몇개의 li들을 다시 뽑아내어 html에 삽입해야 합니다.
문제
gallery.innerHTML = tagArray;
이런 식으로 tagArray 안의 태그들을 그대로 넣었다가는,
배열 내의 쉼표까지 전부 화면에 나타납니다.
그래서 쉼표들을 전부 제거해줘야 했습니다.
해결
검색해보니 join()이라는 메소드가 있더라고요.( join에 대하여 )
배열의 모든 요소를 연결해 하나의 문자열로 만들어주는 메소드입니다.
function addCoffeeList(obj, gallery) {
    let nameIndex = exportName(obj);
    let imgIndex = exportUrl(obj);
    let tagArray = [];
    for (let i = 0; i < obj.length; i++) {
        let listTag = `<li><a class="coffee-thumbnail" href="#">
        <div class="coffee-img">
        <img src="${imgIndex[i]}" alt="${imgIndex[i].substr(4,imgIndex[i].length)}"/>
        </div><p class="coffee-name">${nameIndex[i]}</p></a></li>`
        tagArray.push(listTag);
    }
    
    let tagToString = tagArray.join('');
    gallery.innerHTML = tagToString;
};
곧장 실행해봤더니, 이 방법으로 성공!
이제 객체에 데이터 몇개만 추가해주면 리스트가 저절로 만들어지네요!
//coffee-gall 리스트 추가
const coldBrewList = [{
    name: '나이트로 바닐라 크림',
    imgUrl: 'img/cb-01.jpg'
}, {
    name: '나이트로 콜드 브루',
    imgUrl: 'img/cb-02.jpg'
}, {
    name: '돌체 콜드 브루',
    imgUrl: 'img/cb-03.jpg'
}, {
    name: '바닐라 크림 콜드 브루',
    imgUrl: 'img/cb-04.jpg'
}, {
    name: '벨벳 다크 모카 나이트로',
    imgUrl: 'img/cb-05.jpg'
}, {
    name: '시그니처 더 블랙 콜드 브루',
    imgUrl: 'img/cb-06.jpg'
}, {
    name: '제주 비자림 콜드 브루',
    imgUrl: 'img/cb-07.jpg'
}, {
    name: '콜드 브루',
    imgUrl: 'img/cb-08.jpg'
}, {
    name: '콜드 브루 몰트',
    imgUrl: 'img/cb-09.jpg'
}, {
    name: '콜드 브루 오트 라떼',
    imgUrl: 'img/cb-10.jpg'
}]
const brewedList = [{
    name: '아이스 커피',
    imgUrl: 'img/b-01.jpg'
}, {
    name: '오늘의 커피',
    imgUrl: 'img/b-02.jpg'
}]
//변수 선언
const coldBrewGall = document.querySelector('.cold-brew .coffee-gall'),
    brewedGall = document.querySelector('.brewed .coffee-gall');
//함수 선언
function exportName(data) {
    let coffeeName = [];
    for (let key in data) {
        coffeeName.push(data[key]['name']);
       
    }
    return coffeeName;
}
function exportUrl(data) {
    let coffeeImg = [];
    for (let key in data) {
        coffeeImg.push(data[key]['imgUrl']);
    }
    return coffeeImg;
}
function addCoffeeList(obj, gallery) {
    let nameIndex = exportName(obj);
    let imgIndex = exportUrl(obj);
    let tagArray = [];
    for (let i = 0; i < obj.length; i++) {
        let listTag = `<li><a class="coffee-thumbnail" href="#">
        <div class="coffee-img">
        <img src="${imgIndex[i]}" alt="${imgIndex[i].substr(4,imgIndex[i].length)}"/>
        </div><p class="coffee-name">${nameIndex[i]}</p></a></li>`
        tagArray.push(listTag);
    }
    
    let tagToString = tagArray.join('');
    gallery.innerHTML = tagToString;
};
addCoffeeList(coldBrewList, coldBrewGall);
addCoffeeList(brewedList, brewedGall);
로그인 페이지의 버튼 새로고침 현상 때처럼 스트레스를 받지는 않았지만, 만족할만한 검색 결과가 계속 나오지 않아 꽤 애를 먹었습니다.
그래도 예전 디자이너 시절때 하나하나 html코드로 갤러리를 짰을 때에 비하면 굉장히 많은 발전을 이루었다고 생각해서 뿌듯해집니다.
잘 봤어요 :)