let lastScroll = 0;
$(window).scroll(function(){
curr = $(this).scrollTop();
(curr > 0) ? $('.header').addClass('fixed') : $('.header').removeClass('fixed');
if (curr > lastScroll) { //내릴때
$('.header').addClass('hide');
} else {
$('.header').removeClass('hide');
}
lastScroll = curr; //조건비교 후 따라옴
})
스크롤을 아래로 내렸을 시 header가 사라지고, 스크롤을 위로 올렸을 때 header가 나타나게끔 효과를 줬다.
curr = $(this).scrollTop(); : 현재 스크롤 위치.
let lastScroll = 0; : 스크롤 시작점 값 선언.
if (curr > lastScroll) { $('header').addClass('hide); } else { $('header').removeClass('hide'); } : 현재 스크롤 위치가 타겟 섹션에 도달하기까지의 스크롤 값과 같거나 크다면 header태그에 class hide 을 붙이고, 그게 아니라면 지운다.
lastScroll = curr; : 값이 0인 lastScroll이 현재 스크롤 위치값(curr)과 동일하게 설정됐으므로, 스크롤이 조금이라도 내려가면 header태그에 class hide 가 붙고 아닐 시 class hide 가 없어진다.
/* fixed */
.header.fixed {background: #fff; border-bottom:1px solid #f58220;}
.header.fixed h1.logo .cls-1 { fill: #00316c; }
.header.fixed h1.logo #패스_13577.cls-1 { fill:#ed6b00; }
.header.fixed h1.logo .cls-2 { fill: none; }
.header.fixed h1.logo .cls-3 { clip-path: url(#clip-path); }
.header.fixed .gnb .gnb-item .title {color:#053B72;}
.header.fixed .util-area a {color:#053B72;}
.header.fixed .util-area a.srch .cls-2 { stroke: #053B72; stroke-width: 2px; }
.header.fixed .util-area a.lang .cls-2 { stroke: #053B72; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5px; }
/* hide */
.header.hide {
transform:translateY(-100%);
}
.fixed가 추가 되었을때 header의 background와 logo의 색상이 변경되는데, logo는 img나 background로 두개의 이미지를 만들지 않고, svg path 의 fill값을 변경하여 코드를 최소화하였다.
⭐시맨틱 마크업이란?
시맨틱(Semantic)이란 "의미론적인" 의 뜻을 가지며 마크업(Markup)이란 HTML 태그로 문서를 작성하는 것을 말한다. 따라서, 시맨틱 마크업이란 의미를 잘 전달하도록 문서를 작성하는 것을 말한다.
헤더/푸터에
<header>
와<footer>
사용
메인 컨텐츠에<main>
과<section>
사용
독립적인 컨텐츠에<article>
사용
최상위 제목으로<h1>
사용
순서가 없는 목록으로<ul>
과<li>
사용
네비게이션에<nav>
사용이런 식으로 태그가 가지고 있는 의미에 맞게 사용하는 것인데, 이런 점 이외에도 CSS 스타일을 명시하는 태그를 사용하지 않는 것 또한 시맨틱 마크업의 한 종류이다. 즉, 태그가 가지는 의미 자체가 스타일이라면 이는 마크업 자체가 스타일을 갖는 것이기 때문에 시맨틱 마크업에 적합하지 않다.
예를 들어, 동일한 효과를 부여하는
<strong>
과<b>
태그가 있다. 둘은 동일하게 글자색을 진하게 하지만<b>
태그의 경우는 그 자체가 "bold" 의 약어이기 때문에 태그 자체가 스타일을 가진다고 할 수 있다. 하지만<strong>
의 경우는 "그 안의 내용이 다른 내용보다 더 강조되어야 한다" 라는 의미를 가지기 때문에 시맨틱 마크업에 더 적합하다.
<section class="main-today">
<div class="common-inner">
<h2 class="blind">나눔을 통한 기부</h2>
<div class="group-title">
<p class="title">Today</p>
<div class="date">
<div class="month">
<span>06</span>
</div>
<div class="day">
<span>28</span>
</div>
</div>
<strong class="txt">
나눔을 통해 오늘을<br>
특별하고 소중한 날로<br>
만들어보세요.
</strong>
<a href="">기부안내</a>
</div>
</div>
</section>
.blind {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip:rect(0 0 0 0);
margin:-1px;
}
IR 기법이란?
IR(Image Replacement) 기법은 이미지를 볼 수 없는 사용자에게 적절한 대체 텍스트를 제공하는 것으로 이는 웹 접근성 준수를 위한 스크린 리더 사용자뿐 아니라 검색 엔진의 효과적인 내용 수집을 위해서도 필요하다.
네이버에서 사용하는 IR기법을 사용하였다. IE 구버전에서 인식을 못하는 경우가 있기 때문에 margin:-1px; 을 사용한다.
<nav class="gnb">
<ul class="gnb-list">
<li class="gnb-item">
<a href="" class="title">재단소개</a>
<div class="sub-list">
<ul>
<li><a href="">미래에셋박현주재단 소개</a></li>
<li><a href="">활동성과</a></li>
<li><a href="">활동연혁</a></li>
<li><a href="">이사회</a></li>
<li><a href="">미래에셋 사회공헌</a></li>
</ul>
</div>
</li>
<li class="gnb-item">
<a href="" class="title">해외교환장학</a>
<div class="sub-list">
<ul>
<li><a href="">사업안내</a></li>
<li><a href="">사업개요 및 FAQ</a></li>
<li><a href="">글로벌리포터</a></li>
</ul>
</div>
</li>
<li class="gnb-item">
<a href="" class="title">미래세대지원</a>
<div class="sub-list">
<ul>
<li><a href="">사업안내</a></li>
<li><a href="">청소년 문화체험활동</a></li>
<li><a href="">청소년 비전프로젝트</a></li>
<li><a href="">나만의책꿈터지원</a></li>
<li><a href="">이중언어교재지원</a></li>
</ul>
</div>
</li>
<li class="gnb-item">
<a href="" class="title">기부문화</a>
<div class="sub-list">
<ul>
<li><a href="">기부안내</a></li>
<li><a href="">정기기부</a></li>
<li><a href="">일시기부</a></li>
</ul>
</div>
</li>
<li class="gnb-item">
<a href="" class="title">활동스토리</a>
<div class="sub-list">
<ul>
<li><a href="">활동후기</a></li>
<li><a href="">발행물</a></li>
<li><a href="">뉴스레터</a></li>
</ul>
</div>
</li>
<li class="gnb-item">
<a href="" class="title">재단소식</a>
<div class="sub-list">
<ul>
<li><a href="">공지사항</a></li>
<li><a href="">투명경영</a></li>
<li><a href="">보도자료</a></li>
</ul>
</div>
</li>
</ul>
</nav>
.gnb .gnb-list .gnb-item // class 네이밍 규칙에 맞춰 마크업
$('.gnb .gnb-item').hover(function(){
$(this).find('.sub-list').stop().slideDown();
},function(){
$(this).find('.sub-list').stop().slideUp();
})
<section class="main-shcolarship">
<div class="common-inner">
<div class="group-title">
<h2 class="title">해외교환장학</h2>
<p class="desc">
전 세계를 무대로 더 큰 꿈을 키워갈 <br>
젊음의 가능성을 지원하고 응원합니다.
</p>
</div>
</div>
<div class="contents">
<div class="bg-area"></div>
<div class="deco">
<i class="deco1"></i>
<i class="deco2"></i>
<i class="deco3"></i>
<i class="deco4"></i>
<div class="wave">
<span></span>
<span></span>
</div>
</div>
<ul class="ship-list">
<li class="ship-item">
<h3 class="title">파견 국가수</h3>
<p class="data">
<em class="counter" id="cnt1">50</em>
<span>개국</span>
</p>
</li>
<li class="ship-item">
<h3 class="title">장학생수</h3>
<p class="data">
<em class="counter" id="cnt2">6,217</em>
<span>명</span>
</p>
</li>
<li class="ship-item">
<h3 class="title">운영기간</h3>
<p class="data">
<em class="counter" id="cnt3">16</em>
<span>년</span>
</p>
</li>
</ul>
</div>
</section>
function numberCounter(target_frame, target_number) {
this.count = 0; this.diff = 0;
this.target_count = parseInt(target_number);
this.target_frame = document.getElementById(target_frame);
this.timer = null;
this.counter();
};
numberCounter.prototype.counter = function() {
var self = this;
this.diff = this.target_count - this.count;
if(this.diff > 0) {
self.count += Math.ceil(this.diff / 5);
}
this.target_frame.innerHTML = this.count.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
if(this.count < this.target_count) {
this.timer = setTimeout(function() { self.counter(); }, 30);
} else {
clearTimeout(this.timer);
}
};
let scrollFlag = false;
$(window).scroll(function(){
curr = $(this).scrollTop();
target = $('.main-shcolarship').offset().top; //스크롤 반응 시작지점 값 구하기.
if(curr >= target && scrollFlag == false){
new numberCounter('cnt1' , 50)
new numberCounter('cnt2' , 6479)
new numberCounter('cnt3' , 16)
scrollFlag = true;
}
if(curr >= target-$(window).height()/5){
$('.main-shcolarship .bg-area').addClass('on');
}else{
$('.main-shcolarship .bg-area').removeClass('on');
}
})
scroll 이벤트를 통해 스크롤이 해당 섹션에 도달했을 때 카운팅이 된다.
if(curr >= target && scrollFlag == false) : scrollFlag가 false 일때만 실행되게하여, 한번만 실행되게끔 만들었다.
<section class="main-apply">
<div class="group-title">
<h2 class="title" data-fade>미래세대지원</h2>
<p class="desc" data-fade>
우리 아이들의 꿈이<br>
풍요롭게 성장할 수 있는<br>
지식과 경험의 토양을 만들어갑니다.
</p>
</div>
<div class="contents">
<ul class="apply-list">
<li class="apply-item">
<div class="apply-inner">
<a href="">
<div class="img-wrap">
<img src="./assets/images/main_apply_img1.jpg" alt="청소년 문화체험활동 지원">
</div>
<div class="txt-wrap">
<h3 class="title">
청소년<br>
문화체험활동 지원
</h3>
<p class="desc">
아이들의 미래를 풍요롭게 만들어줄<br>
문화ㆍ예술과의 만남을 선물합니다.
</p>
</div>
</a>
</div>
</li>
<li class="apply-item">
<div class="apply-inner">
<a href="">
<div class="img-wrap">
<img src="./assets/images/main_apply_img2.jpg" alt="청소년 비전프로젝트">
</div>
<div class="txt-wrap">
<h3 class="title">
청소년<br>
문화체험활동 지원
</h3>
<p class="desc">
아이들의 미래를 풍요롭게 만들어줄<br>
문화ㆍ예술과의 만남을 선물합니다.
</p>
</div>
</a>
</div>
</li>
<li class="apply-item">
<div class="apply-inner">
<a href="">
<div class="img-wrap">
<img src="./assets/images/main_apply_img3.jpg" alt="미래의 책꿈터">
</div>
<div class="txt-wrap">
<h3 class="title">
청소년<br>
문화체험활동 지원
</h3>
<p class="desc">
아이들의 미래를 풍요롭게 만들어줄<br>
문화ㆍ예술과의 만남을 선물합니다.
</p>
</div>
</a>
</div>
</li>
<li class="apply-item">
<div class="apply-inner">
<a href="">
<div class="img-wrap">
<img src="./assets/images/main_apply_img4.jpg" alt="베트남어">
</div>
<div class="txt-wrap">
<h3 class="title">
청소년<br>
문화체험활동 지원
</h3>
<p class="desc">
아이들의 미래를 풍요롭게 만들어줄<br>
문화ㆍ예술과의 만남을 선물합니다.
</p>
</div>
</a>
</div>
</li>
</ul>
</div>
</section>
ScrollTrigger.create({
trigger:".main-apply",
start:"0% 0%", //트리거기준 윈도우기준 둘이 만나면 실행
end:"100% 100%", //둘이 만나면 끝
// markers: true,
pin: '.main-apply .group-title',
})
$('.apply-item').each(function(a,b){
gsap.to($(this).find('.img-wrap'),{
scrollTrigger:{
trigger:b,
start:"0% 120%", //트리거기준 윈도우기준 둘이 만나면 실행
end:"100% 0%", //둘 이 만나면 끝
// markers: true,
scrub:1,
},
width:500,
height:500,
})
})
pin: '.main-apply .group-title': 화면 좌측의 group-title 부분을 픽스하기 위해 필요한 옵션이다. position:sticky와 같다고 보면 된다.
$('.apply-item').each(function(a,b){}: 반복문을 통해 스크롤 했을때 각각 .apply-item 마다 따로 스크롤 효과를 주었다. 반복문 없이는 모든 .apply-item 부분들이 전부 똑같이 효과가 적용된다.