Coding Feature.

JS) 별점 시스템 만들기 #1 본문

Programming Language/JavaScript

JS) 별점 시스템 만들기 #1

codingfeature 2023. 1. 17. 18:42

'왓챠피디아'와 같은 앱에서 보이는 별점 시스템을 JavaScript로 구현해보기로 했다.

 

구현 내용은 크게,

1. 마우스 커서를 올릴 때, 별점 수만큼 별이 보인다.

2. 한번 별점을 누르면 그대로 남아있어야 한다.

이다.

 

우선, 

상황에 따라 바뀌는 별점 이미지를 좀더 편하게 관리하기 위해,

starArray 라는 배열을 사용한다.

let starArray = [0, 0, 0, 0, 0];
// 0 is blank star, 1 is full star.

starArray 내 item에서 0은 비어있는 별점, 즉 blank를 나타내고,

1은 full을 나타낸다.

 

또한 사용자가 클릭한 별점 수를 저장하기 위해,

let clickedStar = -1;
// save the number user rated.

clickedStar 변수를 선언한다.

사용자가 아직 누르지 않았을 때를 나타내기 위해 -1로 초기화하였다.

 

그다음 for 반복문을 통해,

별 다섯 개를 만들고,

속성과 Event Listener를 각자 설정한다.

 

for(let i = 0; i<5; i++){
    let starImg = document.createElement('img');

    starImg.setAttribute('class', 'star');
    starImg.setAttribute('src', 'star-trans.png');
    starImg.setAttribute('id', 'star'+i)

    starImg.addEventListener('mouseover', MouseOnStarChangeImg);
    starImg.addEventListener('mouseout', MouseOffStarChangeImg);
    starImg.addEventListener('click', OnClickChangeStarScore);

    allstars.appendChild(starImg);
}

각자의 별 element에는 총 세 가지 event listener를 생성했는데,

MouseOnStarChangeImg에 mouseover 이벤트를, (마우스 커서를 올렸을 때 발생)

MouseOffStarChangeImg에 mouseout 이벤트를, (올린 마우스 커서를 뺄 때 발생)

OnClickChangeStarScore에 click 이벤트를, (클릭 시 이벤트 발생)

생성했다.

 

그리고 앞서 선언한 배열에 담긴 값에 맞게 이미지를 변환하는 함수,

ColorStars도 구현하였다.

먼저 ColorStars의 경우, 

// change img of stars by referencing star array.
function ColorStars(){
    for(let i = 0; i < 5; i++){
        let starTemp = document.getElementById('star'+i);
        if(starArray[i] == Number(1)){
            starTemp.setAttribute('src', 'star.png');
        }else{
            starTemp.setAttribute('src', 'star-trans.png');
        }
    }
}

for 반복문을 통해,

배열의 값이 1이면 full star를, 0이면 blank star를 img 태그의 src 속성을 통해 이미지를 바꾸게 된다.

 

// when user clicks, it changes text, clickedStar variable, and starArray.
function OnClickChangeStarScore(event){
    for(let i=0;i<5;i++){
        if('star'+i === this.id){
            starScore.textContent = i+1;
            clickedStar = i;
            for(let j = 0; j<=i; j++){
                starArray[j] = 1;
            }
        }
    }
}

OnClickChangeStarScore는 사용자가 누른 별 이미지의 ID를 가져와서

1) 텍스트, 2) clickedStar, 3) star array의 값을 변경한다.

 

// when mouse cursor moves out from rating, it calls coloring function.
function MouseOffStarChangeImg(event){

    //if user did not click.
    if(clickedStar === Number(-1)){
        for(let i  = 0; i < 5; i++){
            starArray[i] = 0;
        }
    }else{
        //if user did click.
        for(let i  = 0; i <= clickedStar; i++){
            starArray[i] = 1;
        }
        for(let i  = clickedStar+1; i < 5; i++){
            starArray[i] = 0;
        }
    }
    ColorStars();
}

// when mouse cursor moves into rating, it calls coloring function.
function MouseOnStarChangeImg(event){
    for(let i  = 0; i < 5; i++){
        if(this.id == 'star'+i){
            for(let j = 0; j<=i; j++){
                starArray[j] = 1;
            }
            for(let j = i+1;j<5;j++){
                starArray[j] = 0;
            }
        }
    }
    ColorStars();
}

나머지 두 event listener 함수들은 사용자 마우스 커서의 동작에 맞게 배열의 값을 변경하고

ColorStars() 함수를 호출하여 별점 이미지를 바꾸게 된다.

 

MouseOffStarChangeImg 함수의 경우, clickedStar가 -1일때, 

아직 사용자가 별점을 클릭하기 전이므로 마우스 커서가 빠져나갈때,

모든 배열을 0으로 바꾸어 빈칸이 되도록 한다.

 

결과는 다음과 같다.

구현한 별점 시스템

 

for 문의 중복을 제거하고 좀더 간결하게 작성하는 방향으로 개선할 수 있을 것이다.

이전에 간단하게 만들어보았던 영화 리뷰 사이트에 이번에 구현한 별점 시스템을 잘 결합시켜봐야겠다.