css
.mousePos {
display: inline-block;
background: cornsilk;
padding: 16px;
font-size: 30px;
}
span { font-size: 16px; }
html
<div class="mousePos">마우스 포지션</div>
<div style="height: 1500px"></div>
js
const mousePos = document.querySelector(".mousePos");
document.addEventListener("mousemove", (event) => {
console.log(event);
const cx = event.clientX; // 눈에 보이는 브라우저 화면 기준 좌표
const cy = event.clientY; // event.x event.y와 같음
const px = event.pageX; // 전체 문서 기준 좌표(스크롤 화면 포함)
const py = event.pageY;
const sx = event.screenX; // 모니터 화면 기준 좌표
const sy = event.screenY;
const ox = event.offsetX; // 이벤트 대상이 기준
const oy = event.offsetY;
mousePos.innerHTML = `
<h4>MousePosition</h4>
clientX : ${cx}, clientY : ${cy} <span>눈에 보이는 브라우저 화면 기준 좌표</span><br>
pageX : ${px}, pageY : ${py} <span>전체 문서 기준 좌표(스크롤 화면 포함)</span><br>
screenX : ${sx}, screenY : ${sy} <span>모니터 화면 기준 좌표</span><br>
offsetX : ${ox}, offsetY : ${oy} <span>이벤트 대상 기준 좌표</span><br>
`;
});
css
body { background: black; }
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
filter: invert();
}
.line {
position: absolute;
background: white;
}
.horizontal {
width: 100%; height: 1px;
top: 50%;
}
.vertical {
width: 1px; height: 100%;
left: 50%;
}
.tag {
position: absolute;
top: 50%;
left: 50%;
transform: translate(16px, 16px);
color: lightgray;
font-size: 26px;
}
html
<div class="line horizontal"></div>
<div class="line vertical"></div>
<img src="./target.png" alt="" class="target">
<span class="tag">좌표</span>
js
const horizontal = document.querySelector(".horizontal");
const vertical = document.querySelector(".vertical");
const target = document.querySelector(".target");
const tag = document.querySelector(".tag");
document.addEventListener("mousemove", (event) => {
const x = event.clientX;
const y = event.clientY;
horizontal.style.top = `${y}px`;
vertical.style.left = `${x}px`;
target.style.top = `${y}px`;
target.style.left = `${x}px`;
tag.style.top = `${y}px`;
tag.style.left = `${x}px`;
tag.innerHTML = `${x}px, ${y}px`;
});
css
body { background: black; }
div {
width: 250px;
height: 250px;
margin: 10px;
background: cornsilk
}
.special {
background: lightcoral;
}
section {
position: fixed;
top: 20px;
right: 20px;
}
html
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="special"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<section>
<button class="scroll_to">300px 위치로 스크롤</button>
<button class="scroll_by">100px씩 계속 스크롤</button>
<button class="scroll_into">.special로 스크롤</button>
</section>
js
const btnTo = document.querySelector(".scroll_to");
const btnBy = document.querySelector(".scroll_by");
const btnInto = document.querySelector(".scroll_into");
const special = document.querySelector(".special");
btnTo.addEventListener("click", () => {
// window.scrollTo(0, 500); // window 생략 가능
scrollTo({
top: 300,
behavior: "smooth"
});
});
btnBy.addEventListener("click", () => {
scrollBy(0, 100);
});
btnInto.addEventListener("click", () => {
special.scrollIntoView({
block: "nearest",
behavior: "smooth"
});
});
/*
.scrollTo(X, Y) - 문서의 지정된 위치로 스크롤 (.scroll()과 동일)
.scrollBy(X, Y) - 지정된 수치만큼 계속 스크롤
Element.scrollIntoView() - 엘리먼트 위치로 스크롤
- block : 수직으로 스크롤링 될 떄 정렬 기준
- start(default) / end / center / nearest
- inline : 수평으로 스크롤링 될 때 정렬 기준
- start(default) / end / center / nearest
- behavior
- auto(default) / smooth
*/
css
body { font-family: "noto sans kr", Verdana, Geneva, Tahoma, sans-serif; background: #ddd; }
a { color: inherit; }
header {
position: absolute;
width: 100%;
color: #000;
z-index: 9999;
background: rgba(255, 255, 255, 80%);
backdrop-filter: blur(5px);
text-align: center;
}
header h1 {
line-height: 80px;
border-bottom:1px solid #ccc
}
header h1 i {
font-size: 2em;
color: #8fd4f0;
margin-right: 10px;
}
header h1 span {
font-size: 3em;
font-family: 'Economica', sans-serif;
font-weight: 700;
}
nav {}
nav ul { display: inline-block; }
nav ul::after { display: block; content: ""; clear: both; }
nav li { float: left; }
nav li a {
display: block;
padding: 15px;
font-style: 18px;
}
nav li a:hover { color: #cfcfcf; }
.sticker {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 9999;
background: #ade1ff;
color: #fff;
}
.sticker .header_in {
max-width: 1240px;
margin: auto;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
}
.sticker h1 {}
.sticker h1 i {
font-size: 2em;
color: #fff;
margin-right: 10px;
}
.sticker h1 span {
font-size: 2em;
font-family: 'Economica', sans-serif;
font-weight: 700;
}
.sticker nav li a:hover {
color :#aaa;
}
header.on { background: #000; }
header.on h1 i { color: rgba(255, 255, 255, .7) }
header.on nav li a:hover { color: rgba(255, 255, 255, .3) }
header.on .header_in { height: 50px; }
header.on h1 i {
font-size: 1.5em;
margin-right: 5px;
}
header.on h1 span { font-size: 1.7em; }
header.on nav li a {
padding: 10px;
font-size: 14px;
}
.visual {
width: 100%;
height: 100vh;
}
.visual > div {
width: 100%;
height: 100%;
}
.visual > div video {
/* fullpage에서 이미지나 동영상을 화면에 꽉 채우는 법 */
width: 100%;
height: 100%;
object-fit: cover;
}
section {
width: 960px;
margin: 200px auto;
}
section p {
border: 1px solid #ccc;
padding: 40px;
margin: 20px 0;
}
html
<div class="visual">
<div>
<video src="./img/main.mp4" autoplay muted loop></video>
</div>
</div>
<header>
<h1>
<i class="fa-solid fa-cloud"></i>
<span>Portfolio</span>
</h1>
<nav>
<ul>
<li><a href="#">HOME</a></li>
<li><a href="#">UI/UX</a></li>
<li><a href="#">RESPONSIVE</a></li>
<li><a href="#">REACT</a></li>
<li><a href="#">FRONT END</a></li>
<li><a href="#"></a></li>
</ul>
</nav>
</header>
<!-- scoll 시 위에 고정되어 있는 header START -->
<div class="sticker">
<div class="header_in">
<h1>
<i class="fa-solid fa-cloud"></i>
<span>Portfolio</span>
</h1>
<nav>
<ul>
<li><a href="#">HOME</a></li>
<li><a href="#">UI/UX</a></li>
<li><a href="#">RESPONSIVE</a></li>
<li><a href="#">REACT</a></li>
<li><a href="#">FRONT END</a></li>
<li><a href="#"></a></li>
</ul>
</nav>
</div>
</div>
<!-- scoll 시 위에 고정되어 있는 header END -->
<section id="section">
<p>Aliqua officia occaecat pariatur elit officia quis aliqua cillum et culpa pariatur dolore. Est et nisi irure consequat. Duis ullamco eiusmod id commodo sint est culpa labore pariatur adipisicing exercitation. Occaecat deserunt sunt eu est consectetur ullamco ut ea aliquip consectetur Lorem ea. Ipsum fugiat occaecat do dolor minim in deserunt commodo. Aute ut cupidatat velit eiusmod Lorem ad duis ut aliquip est proident. Ad incididunt amet aliquip excepteur culpa nulla tempor fugiat reprehenderit exercitation do sint. Excepteur velit sint et culpa ea deserunt nostrud excepteur. Eiusmod laboris deserunt eiusmod id irure. Dolore incididunt eiusmod anim sint. Commodo laborum labore laborum ullamco nostrud dolor.</p>
</section>
jQuery
// jQuery - 스크롤 되면 무조건 실행
// $(window).scroll(function () {
// $(".sticker").slideDown(500)
// if ($(window).scrollTop() == 0) {
// $(".sticker").slideUp(200)
// }
// });
// section이 시작하는 부분 or 동영상이 끝나는 부분에서 작동
const headerTop = $('header').offset().top + $('header').height();
console.log(headerTop);
$(window).scroll(function () {
let scroll = $(window).scrollTop();
if (scroll > headerTop) {
$(".sticker").slideDown(500);
} else {
$(".sticker").slideUp(500);
}
});
/*
$(window).scrollTop() - 화면 스크롤이 얼마나 되었는지 반환(메소드, 프로퍼티)
A.offset().top - A가 브라우저 상단에서부터 얼마나 떨어져 있는지 알아와서 반환
*/
section이 시작하는 부분 or 동영상이 끝나는 부분에서 작동