jQueryを使ってエリア外からアコーディオンメニューを開く方法
2022年09月02日みなさん、こんにちは!ヒロックラボの平山です。
コーディングをしていて、こんな経験はありませんか?
『指示されたアニメーションのコードの書き方が分からず、検索してもヒットしない…』
先日、まさにこのような状況に陥ってしまいました。
そのアニメーションとは、
- 1.エリア外からアンカーリンク移動してアコーディオンメニューが開く。
- 2.エリア外のアンカーリンクで、リンク先の項目を含めるアコーディオンメニューが開き、スクロール移動する。
というものでした。
「いくら調べても答えが見つからない」と諦めかけていましたが、試行錯誤しながらなんとか実装できました。
今回は、jQueryを使用して上記2つのアニメーションの実装方法をお伝えしていきます。
目次
jQueryを使用して、エリア外からアコーディオンメニューを開く
今回、実装したいアニメーションは、画像にあるような2つです。
それでは早速、コードを書いていきます。
エリア外からアンカーリンク移動してアコーディオンメニューが開く。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="./">
<title>アコーディオンメニュー</title>
<meta name="description" content="">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="header">
<p>アコーディオンメニュー</p>
</header>
<div class="anchor-wrap">
<div class="section-inner">
<dl class="anchor-unit">
<dt class="anchor-unit_dt">
<a href="#link1">リンク1</a>
</dt>
<dd class="anchor-unit_dd">
<ul>
<li><a href="#link1_1">リンク1-1</a></li>
<li><a href="#link1_2">リンク1-2</a></li>
<li><a href="#link1_3">リンク1-3</a></li>
</ul>
</dd>
</dl>
<dl class="anchor-unit">
<dt class="anchor-unit_dt">
<a href="#link2">リンク2</a>
</dt>
<dd class="anchor-unit_dd">
<ul>
<li><a href="#link2_1">リンク2-1</a></li>
<li><a href="#link2_2">リンク2-2</a></li>
<li><a href="#link2_3">リンク2-3</a></li>
</ul>
</dd>
</dl>
<dl class="anchor-unit">
<dt class="anchor-unit_dt">
<a href="#link3">リンク3</a>
</dt>
<dd class="anchor-unit_dd">
<ul>
<li><a href="#link3_1">リンク3-1</a></li>
<li><a href="#link3_2">リンク3-2</a></li>
<li><a href="#link3_3">リンク3-3</a></li>
</ul>
</dd>
</dl>
</div>
</div>
<div class="accordion-wrap">
<div class="section-inner">
<dl class="accordion-dlist" id="link1">
<dt class="accordion-term">
<h3 class="accordion-subtitle">リンク1</h3>
</dt>
<dd class="accordion-desc">
<ul>
<li id="link1_1">リンク1-1</li>
<li id="link1_2">リンク1-2</li>
<li id="link1_3">リンク1-3</li>
</ul>
</dd>
</dl>
<dl class="accordion-dlist" id="link2">
<dt class="accordion-term">
<h3 class="accordion-subtitle">リンク2</h3>
</dt>
<dd class="accordion-desc">
<ul>
<li id="link2_1">リンク2-1</li>
<li id="link2_2">リンク2-2</li>
<li id="link2_3">リンク2-3</li>
</ul>
</dd>
</dl>
<dl class="accordion-dlist" id="link3">
<dt class="accordion-term">
<h3 class="accordion-subtitle">リンク3</h3>
</dt>
<dd class="accordion-desc">
<ul>
<li id="link3_1">リンク3-1</li>
<li id="link3_2">リンク3-2</li>
<li id="link3_3">リンク3-3</li>
</ul>
</dd>
</dl>
</div>
</div>
<script src="jquery-3.6.0.min.js"></script>
<script src="style.js"></script>
</body>
</html>
/**
* base.css
* ========================== */
body {
font-family: "ヒラギノ角ゴ Pro", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, "MS Pゴシック", "MS PGothic", sans-serif;;
color: #333;
line-height: 2;
}
a {
text-decoration: none;
color: #333;
display: inline-block;
}
a:hover {
opacity: 0.6;
}
.section-inner {
width: 100%;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
/**
* header
* ========================== */
.header {
width: 100%;
padding: 0 80px;
height: 80px;
background-color: #333;
color: #fff;
display: flex;
align-items: center;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
/**
* anchor
* ========================== */
.anchor-wrap {
padding: 80px 0 800px;
}
.anchor-unit {
display: flex;
align-items: center;
width: 100%;
padding: 15px 0;
}
.anchor-unit_dt {
width: 15%;
border-right: 2px solid #ff9b3c;
}
.anchor-unit_dd {
width: 80%;
padding-left: 20px;
}
.anchor-unit_dd ul {
display: flex;
justify-content: flex-start;
align-items: center;
}
.anchor-unit_dd ul li {
padding: 0 15px 0 0;
}
/**
* accordion
* ========================== */
.accordion-wrap {
padding-bottom: 800px;
}
.accordion-dlist:not(:first-child) {
margin-top: 20px;
}
.accordion-term {
align-items: center;
cursor: pointer;
display: flex;
padding: 20px 70px 20px 20px;
position: relative;
background-color: #ff9b3c;
}
.accordion-term::before, .accordion-term::after {
background-color: #c7000a;
content: "";
height: 2px;
margin: 0 auto;
position: absolute;
right: 34px;
top: 50%;
transform: translateY(-50%);
width: 20px;
}
.accordion-term::after {
transform: rotate(90deg);
transition: .3s transform;
}
.accordion-subtitle {
font-size: 16px;
padding-left: 40px;
}
.accordion-desc {
display: none;
font-size: 16px;
line-height: 2;
padding: 35px 115px 35px 100px;
text-align: left;
}
.accordion-term.active::after {
transform: rotate(0);
}
// アコーディオン開いている状態でアンカーリンク移動したときの位置調整
$('a[href^="#"]').click(function(){
var speed = 500;
var href = $(this).attr("href");
var target = $(href == "#" || href == ""? 'html':href);
var position = target.offset().top - 150;
$("html,body").animate({
scrollTop: position
},speed,"swing");
return false;
});
//エリア外からアンカーリンク移動してアコーディオンメニューが開く。
$(function(){
$('.anchor-unit_dt a').on('click', function(){
var href = $(this).attr('href');
var term = $(href).find('.accordion-term');
$(term).toggleClass('active').next('.accordion-desc').slideDown({
step: function(){
var headerHight = 150;
var target = $(href);
var position = target.offset().top - headerHight;
$('body,html').stop().animate({scrollTop:position}, 400), 'swing';
}
});
$('.accordion-term').not($(term)).siblings('.accordion-desc').slideUp();
$('.accordion-term').not($(term)).removeClass('active');
});
});
コードを順番に見ていきます。
まず、アンカーリンクをクリックしたらアニメーションが作動するので、
$('.anchor-unit_dt a').on('click', function(){
});
クリックイベントを記載します。そしてその中に、
- ・該当するアコーディオンメニュータブにactiveクラスをつける
- ・該当するアコーディオンメニューを開く
- ・該当するアコーディオンメニューまでスクロール移動
についてのコードを記載していきます。
var href = $(this).attr('href');
var term = $(href).find('.accordion-term');
$(term).toggleClass('active').next('.accordion-desc').slideDown();
上記コードが、
- ・該当のアコーディオンメニュータブにactiveクラスをつける
- ・該当のアコーディオンメニューを開く
に該当します。
step: function(){
var headerHight = 150;
var target = $(href);
var position = target.offset().top - headerHight;
$('body,html').stop().animate({scrollTop:position}, 400), 'swing';
}
上記コードは、スクロールでアンカーリンク移動になります。
slideDown()の中に記載することで、アコーディオンメニューが開いた後にスクロール移動するため、表示位置がずれることを避けることができます。
1つのメニューが開くときに、他のメニューを閉じたい場合は、下記のコードを記載します。
$('.accordion-term').not($(term)).siblings('.accordion-desc').slideUp();
$('.accordion-term').not($(term)).removeClass('active');
エリア外のアンカーリンクで、リンク先の項目を含めるアコーディオンメニューが開き、スクロール移動する。
$(function(){
$('.anchor-unit_dd a').on('click', function(){
var href = $(this).attr('href');
var desc = $(href).parents('.accordion-desc');
var area = $(desc).parent().find('.accordion-term');
$(area).toggleClass('active').next('.accordion-desc').slideDown({
step: function(){
var headerHight = 150;
var target = $(href);
var position = target.offset().top - headerHight;
$('body,html').stop().animate({scrollTop:position}, 400);
}
});
$('.accordion-term').not($(area)).siblings('.accordion-desc').slideUp();
$('.accordion-term').not($(area)).removeClass('active');
});
});
①と同じように、アンカーリンクをクリックしたらアニメーションが作動するので、
$('.anchor-unit_dd a').on('click', function(){
});
のクリックイベントの中に、
- ・リンク先の要素を含む親要素であるアコーディオンメニューにactiveクラスをつける
- ・リンク先の要素を含むアコーディオンメニューを開く
- ・メニューが開いた後にリンク先までスクロール移動
について記載していきます。
var href = $(this).attr('href');
var desc = $(href).parents('.accordion-desc');
var area = $(desc).parent().find('.accordion-term');
$(area).toggleClass('active').next('.accordion-desc').slideDown();
上記コードが、
- ・リンク先のある親要素であるアコーディオンメニューにactiveクラスをつける
- ・リンク先のあるアコーディオンメニューを開く
に該当します。
ここで気をつけたいところは、リンク先がアコーディオンメニュー内にあるので、リンク先からみて、accordion-descクラス、accordion-termクラスが親要素にあたります。そのため、parent()、parents()メソッドを使い、変数を定義していきます。
アコーディオンが開き、スクロール移動する部分のコードは①と同じです。
さいごに
今回は、jQueryを使って、エリア外からアコーディオンメニューを開く方法についてお伝えしてきました。
「エリア外からアコーディオンメニューを開く」と検索すると、コードの書き方はすぐに出てきました。
しかし、検索して出てきた参考のコードはアコーディオンメニュー単体で、複数のアコーディオンメニューには適応せず、該当するメニュー以外も開いてしまったり、アニメーションがうまく作動しなかったりと思うようにいきませんでした。
そこで、アニメーションの動作を細分化しました。そして細分化した動作を一つひとつクリアしていくことで、解決することができました。
もし、調べても「アニメーションの実装の仕方が分からない!」という時は、アニメーションの動作を一つひとつ細分化してみてください。
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
幅広い知見を活かし、最適解を選ぶWebサイト制作
東京都港区南青山/表参道に近い株式会社ヒロックラボでは、日々エンジニアスキル/デザインスキルを高めております。
最新のデザインとより良いコーディングスキルでお客様のホームページをより最適解に仕上げます。
また、Webサイトを制作する上でCMSツールを導入することも多くありますが、豊富な実績と経験から幅広い知見を得てきたヒロックラボは、お客様の解決すべき課題に適したツールを選定・提案することが可能です。
新規ホームページ制作や検索システムなどお気軽にお問い合わせください。