Easy Table of ContentsはWordpressの目次プラグインとして有名な1つです。
Easy Table of Contentsプラグインは、あるバージョンから日本語見出しのアンカータグをuriencodeするように変更になりました。
こんな感じです。
<a class="ez-toc-link ez-toc-heading-16" href="#%e3%81%be%e3%81%a8%e3%82%81" title="まとめ">まとめ</a>
アンカータグを多言語化対応して意味のある内容にしたいのだと思いますが、この機能変更以降、日本語見出しの目次からのスムーズスクロールでjqueryがエラーになるようになりました。
もちろん原因はプラグイン内部の機能ではなく、テーマ、もしくは他のプラグインに原因があります。
この記事では、Easy Table of Contentsの日本語見出しジャンプでエラーになった時の対処方法をまとめておきます。
以下の記事は同様の原因だと思います。
Easy Table of Contentsプラグインの不具合なの?
エラーの発生個所はEasy Table of Contentsプラグインではありません。
プラグイン以外のスムーズスクロール等の機能でアンカーを参照する時にエラーが起きました。具体的には、もともとあったテーマ側のスムーズスクロール機能でエラーになっていました。
アンカージャンプでエラーが起きる原因
エラーになったテーマ側の記述は以下の部分です。
container = $(this.hash.replace(/\//g, "")
thisにハッシュ(アンカータグ)が入ってきますが、それをjqueryに渡すと以下のエラーになります。
Uncaught Error: Syntax error, unrecognized expression:%e3%81%be%e3%81%a8%e3%82%81
uriencodeされた『%なんちゃら』が曲者で、jqueryセレクタとしては特殊文字の一つ(%)なので、セレクタに使用する時に特殊文字をエスケープしていない場合、簡単にエラーになります。
The following characters have a special meaning in CSS:!
,"
,#
,$
,%
,&
,'
,(
,)
,*
,+
,,
,-
,.
,/
,:
,;
,<
,=
,>
,?
,@
,[
,\
,]
,^
,`
,{
,|
,}
, and~
プラグインのバージョンアップ前は、アンカーに特殊文字が含まれていなかったのに、バージョンアップ後に特殊文字が含まれるようになったことで今回のエラーと相成りました。
jQueryのエラーの修正方法
原因は単純なので、修正方法は特殊文字を追加でエスケープすればいいです。
%を\%に置き換えます。
// container = $('this.hash.replace(/\//g, "")');
container = $(this.hash.replace(/\//g, "").replace(/\%/g,"\\\%"));
Affinger5でもEasy Table of Contentsのアンカーでエラーが出る
Affinger5のsmoothscroll.jsでもセレクタのエラーが出ます。
hrefに入ってきたhashの特殊文字をエスケープしていないのが原因です。
var href = $a.attr('href');
var $target = $(href === '#' || href === '' ? 'html' : href);
以下のように直したら問題ないです。
var href = $a.attr('href').replace(/\%/g,"\\\%");//変更
var $target = $(href === '#' || href === '' ? 'html' : href);
(おススメ)Easy Table of Contentsのアンカーを連番に変更する
Easy Table of Contentsのアンカーをuriencodeされたものではなく、単純な文字列に変更すればjavascriptの変なエラーも出なくなります。
uriencodeをやめるとアンカータグが日本語じゃなくなりますが、日本語見出しのアンカーをそのまま使う必要はないので、jsを修正しなくてよいこの方法が一番良いと思います。
add_filter('ez_toc_url_anchor_target', 'toc_anchor_change', 10, 2);
$my_toc_no = 0;
function toc_anchor_change($return, $heading ) {
global $my_toc_no;
$my_toc_no = $my_toc_no + 1;
return "toc___".$my_toc_no;
}
まとめ
シンプルなテーマを使っていれば、起きないエラーだと思いますが、スムーズスクロールが独自に実装されているテーマやプラグインでは、今回のような問題が起きる可能性はあります。
もしjQueryのエラーが出てしまったら、テーマ側のjsを今回のように修正するしかないです。
プラグインが生成するハッシュタグ自体を変更すれば対応できますが、バージョンアップしてアンカータグをuriencodeした旨味がなくなってしまいます。