メニューを閉じたときに元いた位置から閲覧できるようにするJavascript
by Wataru Adachi
HTML
<div id="wrapper">
<header>
<button type="button" id="openMenu">
<span></span>
<span></span>
<span></span>
</button>
<h1>ハンバーガーボタン</h1>
<nav>
<ul>
<li><a href="#">リスト01</a></li>
<li><a href="#">リスト02</a></li>
<li><a href="#">リスト03</a></li>
<li><a href="#">リスト04</a></li>
<li><a href="#">リスト05</a></li>
<li><a href="#">リスト06</a></li>
<li><a href="#">リスト07</a></li>
<li><a href="#">リスト08</a></li>
<li><a href="#">リスト09</a></li>
<li><a href="#">リスト10</a></li>
<li><a href="#">リスト11</a></li>
<li><a href="#">リスト12</a></li>
<li><a href="#">リスト13</a></li>
<li><a href="#">リスト14</a></li>
<li><a href="#">リスト15</a></li>
<li><a href="#">リスト16</a></li>
<li><a href="#">リスト17</a></li>
<li><a href="#">リスト18</a></li>
<li><a href="#">リスト19</a></li>
<li><a href="#">リスト20</a></li>
</ul>
</nav>
<div id="layer"></div><!-- #layer -->
</header>
<main>
<div class="inner">
<p>この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
<h2>見出しh2</h2>
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
<h3>見出しh3</h3>
この文章はダミーテキストです。文字サイズや行間などを確認するために入れています。これで50文字です。
...
CSS
/* bodyの固定用 */
html.fixed,
body.fixed { /* ドロワーが開いた状態 */
position: fixed;
width: 100%;
height: 100%;
}
header {
width: 100%;
height: 60px;
background-color: #666;
color: #fff;
position: fixed;
top: 0;
z-index: 3;
}
header #openMenu {
width: 35px;
height: 40px;
background-color: #666;
position: absolute;
top: 10px;
left: 10px;
cursor: pointer;
outline: none;
padding: 0;
border: 0;
appearance: none;
z-index: 4;
}
header #openMenu span {
display: block;
width: 100%;
height: 5px;
background-color: #fff;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
header #openMenu span:nth-child(1) {
margin-top: 0;
}
header #openMenu span:nth-child(2) {
margin-top: 5px;
}
header #openMenu span:nth-child(3) {
margin-top: 5px;
}
header h1 {
font-size: 1em;
text-align: center;
line-height: 60px;
margin: 0;
}
header nav {
position: fixed;
/* ここは必ずfixed */
top: 60px;
/* top,left,right,bottomを全て0で指定 */
left: -80%;
right: 0;
bottom: 0;
overflow-y: scroll;
/* fixed内が溢れたときにスクロール */
-webkit-overflow-scrolling: touch;
/* iphone慣性スクロール用 */
width: 60%;
background-color: rgba(0, 0, 0, 0.8);
z-index: 2;
-moz-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
-webkit-transition: all 0.2s linear;
transition: all 0.2s linear;
}
header nav.open { /* ドロワーが開いた状態 */
left: 0;
}
header nav ul {
margin: 0;
padding: 0;
list-style-type: none;
}
header nav ul li {
width: 100%;
height: 45px;
line-height: 45px;
padding-left: 1em;
border-bottom: 1px solid #666;
}
header nav ul li a {
display: block;
width: 100%;
height: 100%;
color: #fff;
}
header nav ul li a:hover {
color: #fff;
text-decoration: underline;
}
header nav ul li+li {
border-top: 1px solid #999;
}
header #layer {
position: fixed;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 1;
display: none;
}
header...
TypeScript
document.addEventListener('DOMContentLoaded', (): void => {
const body: HTMLElement | null = document.querySelector('html') || document.querySelector('body');
const menuBtn: HTMLElement | null = document.getElementById('openMenu');
const nav: HTMLElement | null = document.querySelector('nav');
const layer: HTMLElement | null = document.getElementById('layer');
let scrollPos: number = 0;
function getScroll() {
return Math.max(document.documentElement.scrollTop, document.body.scrollTop, window.scrollY);
}
menuBtn?.addEventListener('click', (): void => {
if (body?.classList.contains('fixed') || nav?.classList.contains('open') || layer?.classList.contains('open')) {
body.classList.remove('fixed');
nav.classList.remove('open');
layer.classList.remove('open');
} else {
scrollPos = getScroll();
body?.classList.add('fixed');
nav?.classList.add('open');
layer?.classList.add('open');
}
if (scrollPos !== 0) {
body?.style.top = `-${String(scrollPos)}px`;
}
});
layer?.addEventListener('click', (): void => {
body?.classList.remove('fixed');
nav?.classList.remove('open');
layer?.classList.remove('open');
if (scrollPos !== 0) {
body?.style.top = '';
window.scrollTo(0, scrollPos);
}
});
});