Inflearn brand logo image

인프런 커뮤니티 질문&답변

미갱이님의 프로필 이미지
미갱이

작성한 질문수

웹 애니메이션을 위한 GSAP 가이드 Part.02

아래 질문 (토이스토리 title에 있는 button에 링크 거는 법)에 대한 해결방법이 이게 맞을까요? 더 좋은 방법이 있으면 알려주세요

해결된 질문

작성

·

24

0

navList.forEach((li, index)=>{

  const roma = ['I', 'II', 'III'];
  const arabic = ['1','2','3']
  const linkAddr = ['naver.com','google.com','inflearn.com'];  // button 링크 주소

  li.addEventListener('click',()=>{

    if(!playing) {
      next = index;

      if(li.classList.contains('active')) return;
      for(let i=0;i < navList.length; i++) {
        navList[i].classList.remove('active');
      }
      li.classList.add('active');

      const addr = /*html*/`location.href='http://${linkAddr[next]}'`;  // button 속성 값

      const tl = gsap.timeline()
      .add(leave[current].play())
      .add(titleLeave.play(),'-=1')
      .set('.title h1',{text:`toystory ${roma[index]}`})
      .set('.title p',{text:`토이스토리 시즌 ${arabic[index]}`},'<')
      .add(enter[next].play())
      .add(titleEnter.play())

      tl.eventCallback('onComplete',()=>{
        const btnLink = document.querySelector('.title button');  // button 요소 가져오기
        btnLink.setAttribute('onclick',addr);   // button의 onclick 속성 추가
        current = next;
        playing = false;
      })

      playing = true;
    }
  })
    
    
})



window.addEventListener('load',()=>{

  
  const tl = gsap.timeline()

  .add(enter1.play())  // enter 타임라인 실행
  .add(titleEnter.play())

  tl.eventCallback('onComplete', () => { 
    const btnLink = document.querySelector('.title button');  //처음 실행시 button에 속성값 추가
    btnLink.setAttribute('onclick',"location.href='http://naver.com'"); //처음 실행시 button에 속성값 추가
    playing = false; 
  })

  // page03()[1].play()  // leave 타임라인 실행


})

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 미갱이님!

질문해 주신 코드에서 버튼에 링크를 다는 방법은 잘 구현하셨습니다. 버튼을 클릭할 때마다 각기 다른 링크로 이동하게 설정할 수 있습니다. 다만, 특정한 개선 포인트 몇 가지를 제안드립니다:

  1. HTTPS 사용: 외부 링크를 설정할 때 보안상의 이유로 http 대신 https를 사용하는 것이 좋습니다.

  2. 함수 분리: eventCallback 내에서 버튼 속성을 추가하는 부분을 별도의 함수로 분리하면 코드의 가독성이 더 좋아질 수 있습니다.

  3. 버튼에 기존 이벤트 처리기 제거: 클릭 이벤트가 누적되지 않도록 새로 설정하는 클릭 이벤트 전에 removeEventListener를 사용해서 기존 이벤트를 제거하는 방법을 고려해볼 수 있습니다.

다음은 이러한 개념을 반영한 개선된 코드 예시입니다:

function setButtonLink(button, url) {
  button.setAttribute('onclick', `location.href='${url}'`);
}

navList.forEach((li, index) => {
  const roma = ['I', 'II', 'III'];
  const arabic = ['1', '2', '3'];
  const linkAddr = ['https://naver.com', 'https://google.com', 'https://inflearn.com'];

  li.addEventListener('click', () => {
    if (!playing) {
      next = index;

      if (li.classList.contains('active')) return;
      navList.forEach(item => item.classList.remove('active'));
      li.classList.add('active');

      const tl = gsap.timeline()
        .add(leave[current].play())
        .add(titleLeave.play(), '-=1')
        .set('.title h1', { text: `toystory ${roma[index]}` })
        .set('.title p', { text: `토이스토리 시즌 ${arabic[index]}` }, '<')
        .add(enter[next].play())
        .add(titleEnter.play());

      tl.eventCallback('onComplete', () => {
        const btnLink = document.querySelector('.title button');
        setButtonLink(btnLink, linkAddr[next]);
        current = next;
        playing = false;
      });

      playing = true;
    }
  });
});

window.addEventListener('load', () => {
  const tl = gsap.timeline()
    .add(enter1.play())
    .add(titleEnter.play());

  tl.eventCallback('onComplete', () => {
    const btnLink = document.querySelector('.title button');
    setButtonLink(btnLink, 'https://naver.com');
    playing = false;
  });
});

이와 같은 수정사항을 적용하시면 기능적으로는 동일하겠지만, 코드 관리 및 가독성이 향상될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

미갱이님의 프로필 이미지
미갱이
질문자

네, 확인 감사합니다.

별도 함수로 분리해서 작성해 봐야겠네요~

미갱이님의 프로필 이미지
미갱이

작성한 질문수

질문하기