자기소개 페이지(3) JS적용

dudgus5766·2021년 7월 27일
13

자기소개 페이지

목록 보기
3/3
post-thumbnail

htmlcss만으로 만들었던 자기소개 페이지🤨
'자바스크립트 배우면 이것도 만들고 저것도 만들고...'
마음속으로 다짐했던 자바스크립트 기능을 넣어보기로 했다.


html이랑 css만 할 때는 편했지? 자바스크립트를 사용하자 에러가 나는 내 웹 페이지..
제발 움직여줘 강아ㅈ..아니 사이트야....

자기소개 페이지 구경가기!

JavaScript 적용 효과 💻

1. 메인 타이틀 타이핑 효과

처음 자기소개 페이지를 만들 때 다른 벨로그 글들을 보며 참고하면서 가장 적용해보고 싶었던 타이핑 효과! htmlcss 만으로 이루어진 정적인 페이지에 타이핑 효과로 동적인 움직임을 만들고 싶었다.
그런데 3줄이나 되는 메인 페이지 텍스트에 효과를 구현해내는 것은 쉽지 않았다.(여러 번의 실패와 구글링으로 터득(?)하긴 했지만..)

타이핑 효과 구현 ⬇️

구현 내용

  • 타이핑 애니메이션 구현
  • 타이핑 줄바꿈 적용
  • 글자를 따라오는 커서 제작

JS 코드 ⬇️

const content = "안녕하세요.\n제 이름은 김영현 입니다.\n소통하는 개발자가 되고 싶어요!"
// 타이핑 하고싶은 텍스트 작성
const text = document.getElementById("dynamic");
let index = 0;
let txt = "";

function typing(){
    if(index < content.length){
    txt += content[index];
    text.innerText = txt;
    index++
    }
}
setInterval(typing,320);

원래 처음에 let txt="";을 통해 빈문자열을 선언하지 않고 진행했지만 왜인지 텍스트 내에 띄어쓰기가 없어진 채로 타이핑이 되었다. 오기로 구글링을 한 결과, https://stackoverflow.com/questions/47768523/empty-spaces-are-ignored-by-the-innertext-property 사이트에서 해답을 찾을 수 있었다!

💡 새롭게 알게된 내용

innerText,textContent 그리고 innerHTML의 차이점

  • textContent : textContent의 값은 식별자 노드의 내부 콘텐츠를 text/plain 으로 파싱한 결과. 즉, 해당 요소 내부의 원시 텍스트(raw text) 이다. 그래서 다른 프로퍼티들에 비해 파싱이 빠르다.
  • innerText : innerText의 값은 텍스트가 최종적으로 (화면에) 렌더링 된 모습, 예를 들어 내용 숨김이나 줄바꿈 같이 의도적인 스타일링이 들어간 후의 모습이 된다.(그래서 텍스트 내 줄바꿈이 적용됐던 것!)
  • innerHTML : innerHTML의 값은 가져온 텍스트에 포함된 태그를 인식하여 태그를 적용시킨 후 문자를 보여준다.
    ** innerHTML은 성능상 좋지 않고 XSS 공격에도 취약하므로 innerHTML은 사용하지 않는 것이 좋다.

출처



2. Top버튼 구현

정확히 말해서 Back-to-top버튼이다. 여러 웹 사이트를 볼 때 사이트 하단에 고정되어 있는 Top버튼은 '클릭'시에 사이트 최상단으로 이동하게 된다. 자바스크립트를 통해 상단까지 부드럽게 스크롤이 되는 효과를 구현했다. 하지만 Top버튼에 쓴 방법 외에 다른 방법을 찾긴 했다.(적용 효과 3번에서 계속 📌)

Top버튼 구현 ⬇️

구현 내용

  • 사이트 스크롤 2/3 지점부터 서서히 나타나는 Top버튼 구현
  • 커서를 올렸을 때 바뀌는 버튼 모양
  • 부드러운 스크롤 구현

JS코드 ⬇️


//top버튼 만들기

let btt = document.getElementById('back-to-top'),
    docElem = document.documentElement, //documentElement는 다큐먼트 자체를 가져온다.
    offset,
    scrollPos,
    docHeight;

//문서 높이 구하기

docHeight = docElem.scrollHeight; // 문서 자체 높이를 docHeight에 넣어준다.
if(docHeight !== 0){
    offset = docHeight / 1.5 ;
}

//스크롤 이벤트 만들기

window.addEventListener('scroll', function(){
    scrollPos = docElem.scrollTop;
    btt.className = (scrollPos > offset) ? 'visible' : '';

    /* if문을 이런식으로 줄인다.
    if(scrollPos > offset){
        btt.className = 'visible';
    }else{
        btt.className = '';
    }
    */
});

// 클릭하면 천천히 스크롤 만들기

btt.addEventListener('click',function(ev){
    ev.preventDefault(); //`ev`를 통해서 전에 있던 링크속성을 가져오고 `.preventDefault`를 통해 속성을 막는다.
    // docElem.scrollTop = 0;
    scrollToTop();
})

function scrollToTop(){
    // 일정시간 마다 할 일 = setInterval(할 일,시간)
    // 할 일 = function(){실제로 할 일}
    // 윈도우 스크롤이 0이 아닐때  window.scrollBy(0,-55);
    // 스크롤 0이면 setInterval을 멈춰야 한다 = clearInterval(멈추려는 이름)
    let scrollInterval = setInterval(function(){
        if(scrollPos !== 0){
            window.scrollBy(0,-100);
        }else{
            clearInterval(scrollInterval);
        }
    },15);
}

CSS코드 ⬇️


#back-to-top{
    font-family: "GmarketSansMedium";
    font-size: 1em;
    position: fixed;
    bottom: 11.7em;
    right: 2.5em;
    background-color: #eaeaea;
    box-shadow: 0 0 0.4em 0 rgba(0, 0, 0, .25);
    color: #383838;
    border-radius: 5px;
    padding: 0.8em;
    text-transform: uppercase;
    transition: all .3s;
    cursor: pointer;
    font-weight: 600;
    display: inline-block;
    opacity: 0;

}

#back-to-top:hover{
    font-family: "GmarketSansbold";
    background-color: #fff;
    color: #4a86ff;
    padding: 0.8em 2.5em;
}

#back-to-top.visible{
    opacity: 1;
}

CSS에서 :hover에 padding값을 바꾸면 커서를 올렸을 시 버튼 크기가 바뀌게 된다.

참고



3. GO!버튼과 스크롤

이전에 올렸던 자기소개 페이지 썸네일을 보면 화살표안에 GO!버튼이 있다. 시간문제로 완성하지 못한 버튼을 구현했다.

GO!버튼 구현 ⬇️

구현 내용

  • GO!버튼 구현
  • 버튼 클릭 시 about 타켓으로 이동
  • 부드러운 스크롤 구현

JS코드 ⬇️


let goBtn = document.getElementById("go");
    aBtn = document.getElementById("menu-about"),
    gBtn = document.getElementById("menu-goal"),
    cBtn = document.getElementById("menu-contact");
// go버튼 뿐 만아니라 다른 menu버튼에도 똑같이 부드러운 스크롤을 적용.

goBtn.addEventListener('click',function(ev){
    ev.preventDefault();
    document.getElementById('about').scrollIntoView({behavior: "smooth", block: "start"})
});
aBtn.addEventListener('click',function(ev){
    ev.preventDefault();
    document.getElementById('about').scrollIntoView({behavior: "smooth", block: "start"})
});
gBtn.addEventListener('click',function(ev){
    ev.preventDefault();
    document.getElementById('goal').scrollIntoView({behavior: "smooth", block: "start"})
});
cBtn.addEventListener('click',function(ev){
    ev.preventDefault();
    document.getElementById('contact').scrollIntoView({behavior: "smooth", block: "start"})
});

아까 Top버튼에서 부드러운 스크롤을 위해 썼던 함수보다 훨씬 간단하게 자바스크립트 내장 함수인 .scrollIntoView를 사용하여 구현했다.

💡 새롭게 알게된 내용

scrollIntoView?
scrollIntoView()는 특정 요소를 기준으로 스크롤을 이동시킨다.

element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter

이처럼 3개의 문법이 존재하는데
첫번째로 어떤 파라미터도 사용하지 않고 사용하거나
두번째로 Boolean 파라미터(true/false)를 사용하거나
(true는 요소의 상단, false는 요소의 하단을 기준으로 한다.)
세번째로 options 오브젝트를 넣어서 사용한다.

문법

  • behavior : 전환 에니메이션 정의 (auto || smooth)
  • block : 수직 정렬 (start || center || end || nearest)
  • inline : 수평 정렬 (start || center || end || nearest)

출처



4. 멀티 슬라이드

페이지 내에 있던 goal 요소들에 slide기능을 구현해보기로 했다. 웹 사이트에서 진행하는 이벤트나 업데이트 소식이 슬라이드로 넘어간다. JQuery가 아닌 JS만으로만 구현해보려고 노력했다!✨

멀티 슬라이드 구현 ⬇️

구현 내용

  • 왼쪽 오른쪽 버튼 제작
  • 끝까지 갔을 시 더이상 넘어가지 않고 다시 되돌아오기

JS코드 ⬇️

let   slides = document.querySelector(".goal-boxes"),
      // `slides`는 left값을 바꿔줄 용도.
      slide = document.querySelectorAll(".goal-boxes li"),
      currentIdx = 0,
      // 버튼을 눌렀을 때 순서를 만들어줘야 함.
      slideCount = slide.length,
      // 마지막인지 구분하기 위해 개수도 있어야 함.
      slideWidth = 300,
      slideMargin = 30,
      prevBtn = document.getElementById("prev"),
      // 이전 버튼
      nextBtn = document.getElementById("next");
      // 다음 버튼


slides.style.width = (slideWidth + slideMargin) * slideCount - slideMargin + 'px';
// 슬라이드의 width에 margin값을 더한거에 슬라이드의 개수를 곱한다음 마지막 마진크기를 빼줌. 
// 문자열로 `px`을 붙여줘야 함.

function moveSlide(num){
    slides.style.left = -num * 330 + 'px';
    // 슬라이드의 left값을 330씩 옆으로 움직여야 함.
    // -num을 해줘야 오른쪽에서 왼쪽으로 이동 가능.

    currentIdx = num;
}

nextBtn.addEventListener('click', function(ev){
    ev.preventDefault();
    nextBtnClick();
});

prevBtn.addEventListener('click', function(ev){
    ev.preventDefault();
    prevBtnClick();
});

function nextBtnClick(){
    if(currentIdx < slideCount - 3){
        moveSlide(currentIdx + 1);
        console.log(currentIdx);
    }else{
        moveSlide(0);
    }
};

function prevBtnClick(){
    if(currentIdx > 0){
        moveSlide(currentIdx - 1);
        console.log(currentIdx);
    }else{
        moveSlide(slideCount - 3);

    }
};

멀티 슬라이드를 구현하기 위해 CSS내 goal 박스들의 스타일을 전부 flex에서 position:absolute로 바꿔주었다.(flex에서 구현할 방법은 없을까 궁금하다..나중에 꼭 찾아보기로)
prev, next 버튼을 클릭할 시 330px씩 양 옆으로 움직이게 되고 함수 내에 else문을 통해 더이상 움직이지 않고 초기화되도록 하였다.

참고

💡 마치며

여러가지 자바스크립트 기능을 구현하면서 '역시 나는 아직 병*이다' 라는 생각이 점점 더 커졌다. 자바스크립트 내에서 코드를 통해 내가 하고싶은(또는 누군가가 하고싶은) 이벤트를 구현하는 게 얼마나 어려운 지를 새삼 깨닫게 된다.

profile
RN App Developer

4개의 댓글

comment-user-thumbnail
2021년 7월 30일

무작정 innerHTML 사용했었는데, 새로운 사실 알게 됐어요! 감사합니다!!✨

1개의 답글
comment-user-thumbnail
2021년 8월 4일

와🙋‍♀️ 좋은 코드 잘 봤습니다👍👏👏

1개의 답글