2020.09.09
AMP対応|プラグインなしで記事内の目次
AMP化しても記事目次のプラグイン「TOC+」「Easy Table of Contents」は機能していましたが、javascriptのエラーが出て、気になるのでプラグインなしで参考になるものを探しました。
AMP対応のスムーススクロールする目次
ラムネグさんのコードを元に見出しへのアンカーリンクをscrollTo
に変更したり、amp-position-observer
を設置したり、AMPに対応させました。
function.php AMP用
function add_mokuji($content){
$threshold = 2; //見出しが2つあれば、目次を表示
if( preg_match_all('/<h([23])>(.*?)<\/h\1>/u', $content, $matches, PREG_SET_ORDER) ){
if( count($matches) >= $threshold ){
$link_no = 1;
$mokuji_title = '<div id="toc-container"><p class="toc-title">この記事の目次</p>';
$mokuji = '<ol>';
$prev_level = 2;
foreach( $matches as $m ){
$level = $m[1];
$text = $m[2];
if($level == 3 && $prev_level == 2){
$mokuji .= '<ol class="indent">';
}
if($level == 2 && $prev_level == 3){
$mokuji .= '</ol>';
}
// scrollToでスムーススクロール 要AMP JS
$mokuji .= '<li><a on="tap:jump-' . $link_no . '.scrollTo(duration= 300)">' . $text . '</a></li>';
$link_no++;
$prev_level = $level;
}
if($prev_level == 3){
$mokuji .= '</ol>';
}
$mokuji .= '</ol>';
// amp-position-observer を設置。目次が画面から消えたら「目次へ戻る」ボタンを表示
$button_target .='<div class="button-target toc"><amp-position-observer on="enter:hideButton.start; exit:showButton.start" layout="nodisplay"></amp-position-observer></div></div>';
$content = preg_replace('/(\s)(<h[23]>.*?<\/h)/u', "$1$mokuji_title$mokuji$button_target$2", $content, 1);
/* 見出しにID付け */
$h_no = 1;
$content = preg_replace_callback(
'/<h([23])>(.*?)<\/h\1>/u',
function($matches) use(&$h_no){
return '<h' . $matches[1] . ' id="jump-' . $h_no++ . '">' . $matches[2] . "</h$matches[1]>";
},
$content
);
}
}
return $content;
}
add_filter('the_content', 'add_mokuji');
?>
目次が消えたら「目次へ戻る」ボタンを表示
目次にamp-position-observer
に設置して画面から目次が消えたら「目次へ戻る」を表示するようにしました。
詳しくはこちら
amp-position-observer
とamp-animation
、2つのコンポーネントを読み込みます。
※WordpressのAMPプラグイン使用している場合はすでに読み込まれています。
header.phpに追加
<!-- amp-position-observerの読み込み -->
<script async custom-element="amp-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script>
<!-- amp-animationの読み込み -->
<script async custom-element="amp-animation" src = "https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
ボタンの表示非表示のアニメーションの設定です。<body>直下に記述します。
body直下に追加
<!-- ボタンを表示するアニメーション -->
<amp-animation id="showButton" layout="nodisplay">
<script type="application/json">{
"duration": "200ms",
"fill": "both",
"iterations": "1",
"direction": "alternate",
"animations": [
{
"selector": "#pagetop",
"keyframes": [
{ "opacity": "1", "visibility": "visible" }
]}
]}
</script>
</amp-animation>
<!-- ボタンを消すアニメーション -->
<amp-animation id="hideButton" layout="nodisplay">
<script type="application/json">{
"duration": "200ms",
"fill": "both",
"iterations": "1",
"direction": "alternate",
"animations": [
{
"selector": "#pagetop",
"keyframes": [
{ "opacity": "0", "visibility": "hidden" }
]}
]}
</script>
</amp-animation>
ボタンの記述はfixed
させるので、どこでもOK。「ページトップに戻る」だとフッターの後に記述することが多いので同じ位置に。
footer.php
<p id="pagetop">
<a id="page-top" on="tap:toc-container.scrollTo(duration = 300)" class="back-toc">目次へ戻る</a>
</p>