서치 이펙트
자바스크립트를 이용한 검색 기능 효과 만들기 입니다.
서치 이펙트 05 - filter( )를 이용하여 속성의 중요도 보여주기
조건 적용이 가능한 filter( ) 메서드를 활용해 범위 검색을 하는 효과입니다.
1. 중요도 정리 및 레이아웃 만들기
속성 별 중요도(숫자)를 설정하고 시각적으로 알 수 있는 버튼을 만드는 작업입니다.
소스보기
-HTML-
<main id="main">
<div class="search__wrap">
<span>filter( )를 이용하여 속성의 중요도 보여주기</span>
<h1>CSS 속성 검색하기</h1>
<div class="search__click">
<ul>
<li data-star="0" class="equel"><a href="#">🌑🌑🌑🌑🌑</a></li>
<li data-star="1" class="equel"><a href="#">⭐🌑🌑🌑🌑</a></li>
<li data-star="2" class="equel"><a href="#">⭐⭐🌑🌑🌑</a></li>
<li data-star="3" class="equel"><a href="#">⭐⭐⭐🌑🌑</a></li>
<li data-star="4" class="equel"><a href="#">⭐⭐⭐⭐🌑</a></li>
<li data-star="5" class="equel"><a href="#">⭐⭐⭐⭐⭐</a></li>
</ul>
<ul>
<li data-star="1" class="up"><a href="#">⭐ 1개 이상</a></li>
<li data-star="2" class="up"><a href="#">⭐ 2개 이상</a></li>
<li data-star="3" class="up"><a href="#">⭐ 3개 이상</a></li>
<li data-star="4" class="up"><a href="#">⭐ 4개 이상</a></li>
</ul>
</div>
<div class="search__info">
<div>전체 속성 갯수 : <span class="num"></span></div>
</div>
<div class="search__list">
<ul class="line">
</ul>
</div>
</div>
</main>
-CSS-
:root {
--htmlColor: #223547;
--cssColor: #5042a4;
--javascriptColor: #6842a4;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'NexonLv1Gothic';
color: var(--htmlColor);
}
*:before, *:after {
box-sizing:border-box;
}
a {
color: var(--htmlColor);
text-decoration: none;
}
li {
list-style: none;
}
/* header */
#header {
display: flex;
justify-content: space-between;
}
#header nav {
margin: 10px;
}
#header nav li {
position: relative;
display: inline;
}
#header nav li a {
width: 30px;
height: 30px;
border: 1px solid var(--htmlColor);
border-radius: 50%;
display: inline-block;
text-align: center;
line-height: 30px;
font-family: 'NexonLv1Gothic';
}
#header nav li.active a {
background-color: var(--htmlColor);
color: #fff;
}
#header nav li .sub {
position: absolute;
left: 0;
top: 35px;
width: 400px;
}
#header nav li .sub li a {
width: auto;
background-color: transparent;
color: var(--htmlColor);
border: 0;
text-align: left;
line-height: 1.2;
}
#header nav li .sub li.active a {
text-decoration: underline;
}
/* main */
#main {
margin: 50px 10px;
}
.search__wrap {
max-width: 1400px;
margin: 0 auto;
border: 3px solid var(--htmlColor);
border-radius: 20px;
background-color: #f1f3f6;
padding: 30px;
text-align: center;
}
.search__wrap > span {
font-size: 20px;
margin-bottom: 20px;
display: inline-block;
}
.search__wrap > h1 {
font-family: 'Tmon';
color: var(--htmlColor);
font-size: 6vw;
margin-bottom: 10px;
}
.search__box {
margin-bottom: 20px;
}
.search__box label {
position:absolute;
clip:rect(0 0 0 0);
width:1px;
height:1px;
margin:-1px;
overflow:hidden
}
.search__box input {
border: 2px solid var(--htmlColor);
padding: 15px 40px;
width: 70%;
border-radius: 50px;
font-size: 20px;
}
.search__list {}
.search__list li {
text-align: left;
line-height: 1.7;
}
.search__list li.show {
display: block;
}
.search__list li.hide {
display: none;
}
.search__list span {
display: inline-block;
padding: 10px 20px;
border: 1px solid var(--htmlColor);
border-radius: 50px;
margin: 5px;
transition: all 0.3s;
cursor: pointer;
}
.search__list span:hover {
background-color: var(--htmlColor);
color: #fff;
}
.search__list em {
float: right;
font-style: normal;
}
.search__list .line {
margin: 50px 0;
}
.search__list .line li {
background: #e3eaf5;
padding: 10px 30px;
margin-bottom: 5px;
border-radius: 50px;
}
.search__list .line li:hover {
background: #d3e2fa;
cursor: pointer;
}
.search__info {
text-align: right;
margin-bottom: 30px;
padding-bottom: 10px;
border-bottom: 2px solid var(--htmlColor);
}
.search__info .type {
text-align: center;
margin-bottom: 10px;
}
.search__info .keyword {
text-align: center;
margin-bottom: 10px;
}
.search__info .keyword span {
border: 2px solid var(--htmlColor);
border-radius: 50px;
padding: 10px;
display: inline-block;
margin-bottom: 4px;
}
.search__info .keyword span:hover {
background-color: var(--htmlColor);
color: #fff;
cursor: pointer;
}
.search__desc {
padding: 21px 40px 20px 60px;
margin-bottom: 50px;
background: #fff;
border-radius: 50px;
display: inline-block;
background-color: var(--htmlColor);
color: #fff;
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='11' cy='11' r='8' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M16.5 16.958L21.5 21.958' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: 22px 17px;
position: relative;
}
.search__desc::before {
content: '';
position: absolute;
left: 52px;
top: 20px;
height: 20px;
padding: 0.3px;
background: rgba(255,255,255,0.6);
}
.search__click {
margin-top: 10px;
margin-bottom: 30px;
}
.search__click li {
display: inline;
}
.search__click li a {
display: inline-block;
border: 1px solid var(--htmlColor);
border-radius: 50px;
padding: 10px 20px;
margin: 5px 0;
}
.search__click li a:hover {
background-color: var(--htmlColor);
color: #fff;
}
@media (max-width: 600px){
.search__wrap {
padding: 20px;
}
.search__wrap > span {
font-size: 16px;
margin-bottom: 10px;
}
.search__wrap > h1 {
font-size: 40px;
}
.search__wrap input {
font-size: 16px;
padding: 12px 30px;
}
}
/* footer */
#footer {
text-align: center;
}
#footer a {
color: #000;
font-family: 'NexonLv1Gothic';
padding-bottom: 50px;
}
#footer a:hover {
text-decoration: underline;
}
-배열 데이터-
const cssProperty = [
{ star: 1, name: "accent-color", desc: "속성은 특정 요소에 색상을 지정할 때 사용됩니다." },
{ star: 5, name: "align-content", desc: "콘텐츠 아이템의 상하관계 정렬 상태를 설정합니다." },
{ star: 5, name: "align-items", desc: "콘텐츠 아이템의 내부 상하관계 정렬 상태를 설정합니다." },
{ star: 5, name: "align-self", desc: "개별적인 콘텐츠 아이템의 정렬 상태를 설정합니다." },
{ star: 5, name: "all", desc: "요소의 속성을 초기화 또는 상속을 설정합니다." },
{ star: 5, name: "animation", desc: "애니메이션과 관련된 속성을 일괄적으로 설정합니다." },
{ star: 5, name: "animation-delay", desc: "애니메이션 지연 시간을 설정합니다." },
{ star: 5, name: "animation-direction", desc: "애니메이션 움직임 방향을 설정합니다." },
{ star: 5, name: "animation-duration", desc: "애니메이션 움직임 시간을 설정합니다." },
{ star: 5, name: "animation-fill-mode", desc: "애니메이션이 끝난 후의 상태를 설정합니다." },
{ star: 5, name: "animation-iteration-count", desc: "애니메이션의 반복 횟수를 설정합니다." },
{ star: 5, name: "animation-name", desc: "애니메이션 keyframe 이름을 설정합니다." },
{ star: 3, name: "animation-play-state", desc: "애니메이션 진행상태를 설정 합니다." },
{ star: 4, name: "animation-timeline", desc: "x" },
{ star: 3, name: "animation-timing-function", desc: "애니메이션 움직임의 속도를 설정 합니다." },
{ star: 2, name: "appearance", desc: "운영체제 및 브라우저에 기본적으로 설정되어 있는 테마를 기반으로 요소를 표현합니다." },
{ star: 1, name: "aspect-ratio", desc: "요소의 크기를 비율대로 조정할 수 있게 합니다." },
{ star: 4, name: "backdrop-filter", desc: "요소 뒤 영역에 흐림이나 색상 시프트 등 그래픽 효과를 적용할 수 있는 속성입니다." },
{ star: 5, name: "backface-visibility", desc: "입체적인 모습의 뒷면의 가시성을 결정하는 속성이다." },
{ star: 5, name: "background", desc: "백그라운드 속성을 일괄적으로 설정 합니다." },
{ star: 1, name: "background-attachment", desc: "배경 이미지의 고정 여부를 설정 합니다." },
{ star: 1, name: "background-blend-mode", desc: "배경을 혼합했을 때 그래픽 효과를 설정 합니다." },
{ star: 2, name: "background-clip", desc: "백그라운드 이미지의 위치 기준점을 설정 합니다." },
{ star: 5, name: "background-color", desc: "백그라운드 색을 설정 합니다." },
{ star: 5, name: "background-image", desc: "백그라운드 이미지 속성을 설정 합니다." },
{ star: 1, name: "background-origin", desc: "백그라운드 이미지의 위치 기준점을 설정하기 위한 속성입니다." },
{ star: 5, name: "background-position", desc: "백그라운드 이미지의 위치 영역을 설정 합니다." },
{ star: 4, name: "background-position-x", desc: "백그라운드 이미지의 x축 위치 영역을 설정 합니다." },
{ star: 4, name: "background-position-y", desc: "백그라운드 이미지의 y축 위치 영역을 설정 합니다." },
{ star: 5, name: "background-repeat", desc: "백그라운드 이미지 반복 여부를 설정 합니다." },
{ star: 5, name: "background-size", desc: "백그라운드 이미지 사이즈를 설정 합니다." },
{ star: 2, name: "block-size", desc: "기록 모드에 따라서, 요소의 블록의 수평과 수직 크기를 정의합니다." },
{ star: 5, name: "border", desc: "테두리 속성을 일괄적으로 설정 합니다." },
{ star: 0, name: "border-block", desc: "X" },
{ star: 0, name: "border-block-color", desc: "x" },
{ star: 0, name: "border-block-end", desc: "x" },
{ star: 0, name: "border-block-end-color", desc: "x" },
{ star: 0, name: "border-block-end-style", desc: "x" },
{ star: 0, name: "border-block-end-width", desc: "x" },
{ star: 0, name: "border-block-start", desc: "x" },
{ star: 0, name: "border-block-start-color", desc: "x" },
{ star: 0, name: "border-block-start-style", desc: "x" },
{ star: 0, name: "border-block-start-width", desc: "x" },
{ star: 0, name: "border-block-style", desc: "x" },
{ star: 0, name: "border-block-width", desc: "x" },
{ star: 5, name: "border-bottom", desc: "아래쪽 속성을 일괄적으로 설정 합니다." },
{ star: 5, name: "border-bottom-color", desc: "테두리 아래쪽 색 속성을 설정합니다." },
{ star: 5, name: "border-bottom-left-radius", desc: "아래 왼쪽 모서리 굴곡을 설정합니다." },
{ star: 5, name: "border-bottom-right-radius", desc: "아래 오른쪽 모서리 굴곡을 설정합니다." },
{ star: 5, name: "border-bottom-style", desc: "아래쪽 테두리의 스타일 속성을 설정합니다." },
{ star: 5, name: "border-bottom-width", desc: "아래쪽 테두리의 두께 속성을 설정합니다." },
{ star: 4, name: "border-collapse", desc: "테이블의 테두리를 겹칠지, 떨어트릴지를 설정합니다." },
{ star: 4, name: "border-color", desc: "모든 면의 테두리 색상을 설정 합니다." },
{ star: 2, name: "border-end-end-radius", desc: "요소의 테두리 반경을 설정 합니다." },
{ star: 2, name: "border-end-start-radius", desc: "요소의 테두리 반경을 설정 합니다." },
{ star: 1, name: "border-image", desc: "요소의 주위에 이미지를 설정 합니다." },
{ star: 1, name: "border-image-outset", desc: "테두리 상자와 테두리 이미지의 거리를 설정 합니다." },
];
css 속성을 적은 배열 데이터에 이름과 설명 뿐만 아니라 중요도 표시를 위한 star 키 값을 추가했습니다.
또한 검색 효과를 위해 star값과 매칭하기 위한 data- 속성도 추가했습니다.
2-1. filter( ) 메서드를 활용해 검색 효과 만들기
dataset 값과 객체 데이터의 star 키 값을 매치해 같은 값을 가진 변수를 함수로 실행해 해당 중요도 속성만 출력하도록 합니다.
소스보기
-스크립트 파트-
const searchList = document.querySelector(".search__list ul");
const searchClick1 = document.querySelectorAll(".search__click ul li.equel");
const searchClick2 = document.querySelectorAll(".search__click ul li.up");
const searchStar = document.querySelector(".search__click ul li a").innerText;
const searchInfo = document.querySelector(".search__info .num");
// 출력하기
function updateList(list){
listCSS = "";
for (const data of list){
listCSS += `<li>${data.name} : ${data.desc} <em>${data.star}</em></li>`;
}
searchList.innerHTML = listCSS;
}
updateList(cssProperty);
// 클릭하기
searchClick1.forEach((star, index)=> {
star.addEventListener("click", () => {
const target = star.dataset.star;
const filterList = cssProperty.filter(data => data.star == target);
updateList(filterList);
});
});
출력시 listCSS += 라고 한 이유는 = 를 사용하면 데이터가 변수의 데이터 수정 효과로 계속 덧씌워져서 마지막 데이터만 출력되기 때문입니다.
따라서 += 을 사용해 데이터 추가를 해야 모든 데이터가 출력됩니다.
이벤트 메서드로 클릭 시 dataset.value(star.dataset.star)가 html에서 설정해둔 data 값을 호출합니다.
이 값을 filter( ) 메서드로 데이터 변수인 cssProperty의 star 키 값과 같은 값을 출력 함수에 매개변수로 넣어 실행하면 해당 속성 데이터만 출력하게 됩니다.
2-2. dataset.value를 안쓰고 활용
dataset을 안쓰고 index값을 사용할 수 도 있습니다.
소스보기
-index 활용-
// 클릭하기
searchClick1.forEach((star, index)=> {
star.addEventListener("click", () => {
// const target = star.dataset.star;
// const filterList = cssProperty.filter(data => data.star == target);
------- //index를 활용한 데이터 매칭 --------------------------------------
const filterList = cssProperty.filter(data => data.star == index);
updateList(filterList);
});
});
searchClick1 변수는 중요도(별)의 li 이므로 인덱스 값은 중요도와 똑같이 0-5의 값이 나옵니다. 따라서 dataset.value 대신 index를 넣어도 똑같은 결과를 얻게 됩니다.
3. 범위 검색 및 중요도 숫자 별 치환
filter( ) 메서드를 사용해 범위 검색 효과를 만들고 중요도의 숫자를 별 그림으로 출력하는 작업입니다.
소스보기
-범위 검색 및 별 치환-
// 출력하기
function updateList(list){
listCSS = "";
for (const data of list){
// listCSS += `<li>${data.name} : ${data.desc} <em>${data.star}</em></li>`;
--------//별 출력 switch문
switch (data.star) {
case 0:
listCSS += `<li>${data.name} : ${data.desc} <em>🌑🌑🌑🌑🌑</em></li>`;
break;
case 1:
listCSS += `<li>${data.name} : ${data.desc} <em>⭐🌑🌑🌑🌑</em></li>`;
break;
case 2:
listCSS += `<li>${data.name} : ${data.desc} <em>⭐⭐🌑🌑🌑</em></li>`;
break;
case 3:
listCSS += `<li>${data.name} : ${data.desc} <em>⭐⭐⭐🌑🌑</em></li>`;
break;
case 4:
listCSS += `<li>${data.name} : ${data.desc} <em>⭐⭐⭐⭐🌑</em></li>`;
break;
case 5:
listCSS += `<li>${data.name} : ${data.desc} <em>⭐⭐⭐⭐⭐</em></li>`;
break;
}
}
searchList.innerHTML = listCSS;
}
updateList(cssProperty);
// 조건문 들어간 범위 검색-------------------------------------------------------
searchClick2.forEach((star,index) => {
star.addEventListener("click", () => {
// const target = star.dataset.star;
// const filterList2 = cssProperty.filter(data => data.star >= target);
const filterList2 = cssProperty.filter(data => data.star >= index+1);
updateList(filterList2);
});
});
// 전체 속성 갯수 표시
const searchNum = document.querySelectorAll(".search__list ul li").length;
searchInfo.textContent = searchNum;
filter( ) 메서드는 find( ) 메서드와 같이 배열 값을 서치하는 메서드이지만 filter( ) 메서드는 조건부를 지정할 수 있다는 차이점이 있습니다.
이를 이용해 좀 더 다양한 검색 효과를 만들 수 가 있습니다.
filter( ) 메서드
filter( ) 메서드는 주어진 함수의 조건을 만족하는 모든 요소를 모아 새로운 배열로 반환합니다.
find( )메서드와의 차이점은 조건을 사용할 수 있다는 것 입니다.
filter(e => e 조건 찾을 값)
댓글