SWELLにある『目次がモーダルでポップアップする機能』をCocoonでも導入することができます。
ぽんひろさんの以下の記事に詳細が書かれているので、Cocoonでしたら基本コピペでOKです。

【Cocoon】スマホで目次を追従させる方法
WordPressテーマ「Cocoon」利用者むけのスマホで目次を追従するカスタマイズです。縦長になりがちなスマホにオススメのカスタマイズです。離脱率も下がるかもしれません!コピペで簡単なのでぜひやって見てください。
個人的に気になったところ
- wp_is_mobile()が使われている
- PC/SPのキャッシュが分かれていない場合、キャッシュプラグインとの相性が悪そう
- jQueryでスクリプトが書かれている
- 非jQueryな人はjQueryを読み込まないといけない
- モーダル表示時に背景がスクロールしてしまう
- 目次がスクロールする場合に操作できなくなることがある
気になったところを変更してみる
①wp_is_mobile()が使われている
SPの時だけスクリプト全体を読み込むように条件判定している部分にwp_is_mobile()があります。
wp_is_mobile()はキャッシュプラグインと相性が悪いので避けたいです。
修正方法としては、2つ方法があります。
- PCでも目次を表示する
- wp_is_mobile()をソースから消すだけでいいです。
- PCでは目次を表示しない
- wp_is_mobile()をソースから消して、かつ、目次ボタンをCSSで消してあげればいいです。
変更前
<?php if ( wp_is_mobile() && is_single()) : ?>
<?php if(is_active_sidebar('mobile_toc_widget')) : ?>
<div id="mobile-toc-widget-wrap">
<label for="mobile-toc">
<div class="mobile-toc-button">
<div class="menu-trigger">
<span></span>
<span></span>
<span></span>
</div>
<span class="mobile-toc-button-title">目次</span>
</div>
</label>
<input type="checkbox" id="mobile-toc"/>
<div class="mobile-toc-show">
<div class="mobile-toc-widget">
<?php dynamic_sidebar('mobile_toc_widget'); ?>
</div>
</div>
</div>
<script>
:
</script>
<?php endif; ?>
<?php endif; ?>
変更後(wp_is_mobileを削除)
<?php if ( is_single()) : ?>
<?php if(is_active_sidebar('mobile_toc_widget')) : ?>
<div id="mobile-toc-widget-wrap">
<label for="mobile-toc">
<div class="mobile-toc-button">
<div class="menu-trigger">
<span></span>
<span></span>
<span></span>
</div>
<span class="mobile-toc-button-title">目次</span>
</div>
</label>
<input type="checkbox" id="mobile-toc"/>
<div class="mobile-toc-show">
<div class="mobile-toc-widget">
<?php dynamic_sidebar('mobile_toc_widget'); ?>
</div>
</div>
</div>
<script>
//スマホ目次追尾
jQuery('#mobile-toc-widget-wrap label').on('click', function() {
jQuery('.menu-trigger').toggleClass('active');
});
jQuery('#mobile-toc-widget-wrap .toc-list a').on('click', function() {
jQuery('.menu-trigger').toggleClass('active');
});
jQuery('#sidebar-menu-input').on('click', function() {
if (jQuery('#sidebar-menu-input').prop('checked')) {
jQuery('#mobile-toc-widget-wrap').css('display', 'none');
}else{
jQuery('#mobile-toc-widget-wrap').css('display', 'block');
}
});
jQuery('#mobile-toc-widget-wrap .toc-list a').click(function() {
if (jQuery('#mobile-toc-widget-wrap input').prop('checked')) {
jQuery('#mobile-toc-widget-wrap input').prop('checked', false);
}
});
//スムーススクロール
jQuery(function () {
var headerHight = 50;
jQuery('a[href^="#"]').click(function(){
var href= jQuery(this).attr("href");
var target = jQuery(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top-headerHight;
jQuery("html, body").animate({scrollTop:position}, 550, "swing");
return false;
});
});
</script>
<?php endif; ?>
<?php endif; ?>
PCでは表示しない場合(目次ボタンをCSSで消す)
ブレークポイントはテキトウです。
@media screen and (min-width: 960px){
#mobile-toc-widget-wrap{display:none;}
}
②jQueryでスクリプトが書かれている
スマホ追従目次の部分のjavascriptがjQueryで書かれています。
非jQueryな人はVanilla JSに書き換えたバージョンに差し替えます。
スムーススクロールは、こちらから拝借しました。
【JavaScript】スムーススクロールをjQueryを使わずにシンプルに実装する【Vanilla JS】 – ノーズブログ
jQuery
<script>
//スマホ目次追尾
jQuery('#mobile-toc-widget-wrap label').on('click', function() {
jQuery('.menu-trigger').toggleClass('active');
});
jQuery('#mobile-toc-widget-wrap .toc-list a').on('click', function() {
jQuery('.menu-trigger').toggleClass('active');
});
jQuery('#sidebar-menu-input').on('click', function() {
if (jQuery('#sidebar-menu-input').prop('checked')) {
jQuery('#mobile-toc-widget-wrap').css('display', 'none');
}else{
jQuery('#mobile-toc-widget-wrap').css('display', 'block');
}
});
jQuery('#mobile-toc-widget-wrap .toc-list a').click(function() {
if (jQuery('#mobile-toc-widget-wrap input').prop('checked')) {
jQuery('#mobile-toc-widget-wrap input').prop('checked', false);
}
});
//スムーススクロール
jQuery(function () {
var headerHight = 50;
jQuery('a[href^="#"]').click(function(){
var href= jQuery(this).attr("href");
var target = jQuery(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top-headerHight;
jQuery("html, body").animate({scrollTop:position}, 550, "swing");
return false;
});
});
</script>
Vanilla JS
//スマホ目次追尾
var el = document.querySelector('#mobile-toc-widget-wrap label');
var toggle_el = document.querySelector('.menu-trigger');
el.onclick = function() {
toggle_el.classList.toggle('active');
}
var alinks = document.querySelectorAll("#mobile-toc-widget-wrap .toc-list a")
var el_input = document.querySelector('#sidebar-menu-input');
var el_wrap = document.querySelector('#mobile-toc-widget-wrap');
if(el_input){
el_input.onclick = function() {
if(el_input.checked){
el_wrap.style.display = "none";
}else{
el_wrap.style.display = "block";
}
}
}
const el2 = document.querySelector('#mobile-toc-widget-wrap input');
for (i = 0; i < alinks.length; i++) {
alinks[i].onclick =function(){
if(el2.checked){
el2.checked=false;
}
toggle_el.classList.remove('active');
}
}
//スムーススクロール
var scrollElm = (function() {
if('scrollingElement' in document) return document.scrollingElement;
if(navigator.userAgent.indexOf('WebKit') != -1) return document.body;
return document.documentElement;
})();
(function() {
var headerHight = 60;
var duration = 500;
var ignore = '.noscroll';
var easing = function (t, b, c, d) { return c * (0.5 - Math.cos(t / d * Math.PI) / 2) + b; }; //jswing
var smoothScrollElm = document.querySelectorAll('a[href^="#"]:not(' + ignore +')');
Array.prototype.forEach.call(smoothScrollElm, function(elm) {
elm.addEventListener('click', function(e) {
e.preventDefault();
var targetElm = document.querySelector(elm.getAttribute('href'));
if(!targetElm) return;
var targetPos = targetElm.getBoundingClientRect().top - headerHight ;
var startTime = Date.now();
var scrollFrom = scrollElm.scrollTop;
(function loop() {
var currentTime = Date.now() - startTime;
if(currentTime < duration) {
scrollTo(0, easing(currentTime, scrollFrom, targetPos, duration));
window.requestAnimationFrame(loop);
} else {
scrollTo(0, targetPos + scrollFrom);
}
})();
})
});
})();
③モーダル表示時に背景がスクロールしてしまう
iOSのモーダル表示時の背景スクロール問題は結構有名ですので、他の方が解決した方法を借用します。

モーダルウインドウを背景固定にしてスクロールバー分のガタつき問題を解決しつつ、iOS Safariにも対応してしかもjQuery非依存にしたいワガママなアナタへ捧ぐ愛のコード | ma-ya's CREATE / WEB DESIGN
もはやモーダルウインドウの実装なんて当たり前の要件となってきた昨今、サクッとプラグインを使えば、世の中の優秀なフロントエンド開発者が実装した機能を簡単に使うことができますね。ただそれでも、JSに対する興味や情熱から、自前のコードで実装したい...
適用の仕方は簡単なので概要だけ。
.active classがトグルした時のactive classの有無で、スクロール固定と解除を切り替えればいいです。
注意点としては、addEventListenerOnce(modal, ‘transitionend’, function () {})が引っかかる場合があるので、その場合はコメントアウトすれば大丈夫。
最終形(モーダル背景固定は含まず)
<?php
add_action('wp_footer',function(){ ?>
<?php if ( is_single()) : ?>
<?php if(is_active_sidebar('mobile_toc_widget')) : ?>
<div id="mobile-toc-widget-wrap">
<label for="mobile-toc">
<div class="mobile-toc-button">
<div class="menu-trigger">
<span></span>
<span></span>
<span></span>
</div>
<span class="mobile-toc-button-title">目次</span>
</div>
</label>
<input type="checkbox" id="mobile-toc"/>
<div class="mobile-toc-show">
<div class="mobile-toc-widget">
<?php dynamic_sidebar('mobile_toc_widget'); ?>
</div>
</div>
</div>
<script>
//スマホ目次追尾
var el = document.querySelector('#mobile-toc-widget-wrap label');
var toggle_el = document.querySelector('.menu-trigger');
el.onclick = function() {
toggle_el.classList.toggle('active');
}
var alinks = document.querySelectorAll("#mobile-toc-widget-wrap .toc-list a")
var el_input = document.querySelector('#sidebar-menu-input');
var el_wrap = document.querySelector('#mobile-toc-widget-wrap');
if(el_input){
el_input.onclick = function() {
if(el_input.checked){
el_wrap.style.display = "none";
}else{
el_wrap.style.display = "block";
}
}
}
const el2 = document.querySelector('#mobile-toc-widget-wrap input');
for (i = 0; i < alinks.length; i++) {
alinks[i].onclick =function(){
if(el2.checked){
el2.checked=false;
}
toggle_el.classList.remove('active');
}
}
var scrollElm = (function() {
if('scrollingElement' in document) return document.scrollingElement;
if(navigator.userAgent.indexOf('WebKit') != -1) return document.body;
return document.documentElement;
})();
(function() {
var headerHight = 60;
var duration = 500;
var ignore = '.noscroll';
var easing = function (t, b, c, d) { return c * (0.5 - Math.cos(t / d * Math.PI) / 2) + b; }; //jswing
var smoothScrollElm = document.querySelectorAll('a[href^="#"]:not(' + ignore +')');
Array.prototype.forEach.call(smoothScrollElm, function(elm) {
elm.addEventListener('click', function(e) {
e.preventDefault();
var targetElm = document.querySelector(elm.getAttribute('href'));
if(!targetElm) return;
var targetPos = targetElm.getBoundingClientRect().top - headerHight ;
var startTime = Date.now();
var scrollFrom = scrollElm.scrollTop;
(function loop() {
var currentTime = Date.now() - startTime;
if(currentTime < duration) {
scrollTo(0, easing(currentTime, scrollFrom, targetPos, duration));
window.requestAnimationFrame(loop);
} else {
scrollTo(0, targetPos + scrollFrom);
}
})();
})
});
})();
</script>
<?php },99);
まとめ
脱jQueryが当たり前になってきていますが、オリジナルのjQueryのスクリプトがダメというわけではありません。
jQueryライブラリを読み込んでいるのであれば、この程度の記述量だったら違いはないと思います。
jQueryライブラリを読み込みたくない人には役にたつかもしれませんが、Cocoon自体がjQueryを読み込んでるという・・・