vanillaice (Akira)

vanillaice (Akira)

特定環境下で衝突するんですよ (´・ω・`)
特定というと狭い範囲のように思いますが、広範です。

条件

  • HTML5テンプレート を利用している
  • 開閉プラグインが開閉トリガーに aタグ を用いている
  • テンプレートにページ内スクロール(スムーススクロール)が導入されている

この条件が重なった時ですね。

挙動

  • 開閉ボタンをクリックすると ページ最上部にスクロールしてしまう

この原因と対策についてです。

その前に、上記とは異なる挙動の場合もありますよね。
初期状態で閉じているべきものが開いている(クリックも効かない)
逆もまた然り。
こちらについてはまた別の原因ですので以下の記事を参照のこと。

FC2ブログプラグインの動作確認をお願いします【あなたのプラグインが動かない理由】 - カスタマイズ

FC2ブログには プラグイン というのが用意されていますよね。主にサイドメニュー部に簡単設置できて便利。そして多種多様なものがあります。中でも展開型プラグインは人気が高いような気がします。アーカイブやコメントなどを 折りたたむ系 ですね。公式プラグインというのはJS(Javascript じゃばすくりぷと)を極力使わない というのが制作理念のようです。従って大変シンプルなものが多い。一方、有志ユーザーさんが提供するとこ...

変わってしまった aタグ の仕様

a(アンカー) というhtmlタグですが、html4からhtml5に移行するにあたり仕様が変更されています。

  • name属性の廃止
  • ダミーリンク(空リンク)の使い方変更

他にもありますが、今回の件に大きく関わる内容は上記2つです。

name属性廃止

html4時代の ページ内リンク というのは以下のようなことをしていたんですね

出発点

<a href="#jump">クリックすると移動します</a>

到達点

<a name="jump">ここが目的の位置です</a>

ページ遷移ではないですよ。ページ内移動 です。念のため。
到達点の要素に対し、name属性を用いて目的地名称とします。
それが旧式です。

現在ではどうするかというと

出発点

<a href="#jump">クリックすると移動します</a>

到達点

<div id="jump">ここが目的の位置です</div>

出発点の方の書き方は同じです。到達点の方が違います。
html5では name属性が廃止 されているのと、到達点を a として設置する必要も無し になっているのですね (´・ω・`)
目的地名称はaタグのname属性を利用するのではなく、各要素のid名を利用するという形に変更されています。
というのは、idを目的地名称とした場合にはaタグでのマークアップに限定される不都合が無いわけです。
例えば「見出し」のマークアップは <hx>(xは1〜6までの数字) ですよね。
じゃあそこへ飛ばすために見出しを <a> としてマークアップするの? ってことになります。
それはどう考えてもセマンティックではないですよね。
html5の理念というのは セマンティクス ですので、理に適っていない定義は軒並み廃止や変更が行われています。

そもそもページ内リンクの方法がhtml4とhtml5では 違う

というのがまずひとつ。

ダミーリンク(空リンク)の使い方も変更されている

空リンク(ページ遷移なし、移動なし)というのはどういう時に使うかというと、html4時代はそれこそ 開閉スイッチ に用いたり。
別の言い方をすると プレイスホルダー (place holder)。
こんな感じ

<a href="#">クリックすると開閉します</a>

ページ遷移も移動もさせず、スイッチとして利用する。
html5ではもうそういうことはしません。
ダミーが必要な場合には

<a>クリックすると開閉します</a>

これでOK。
というよりもスイッチにaタグを用いる必要すらありません。
<button> とかがありますから、わざわざ定義を曲げてまで <a> を使う理由はどこにもありません。

html4に於いては href属性が必須 でしたので、書かなきゃ仕方がなかったんですね。不要でも。
その旧仕様が諸悪の根源です

スムーススクロールとの衝突

ページ内で移動する際にスルスル〜っと動くアレです。
何故このスムーススクロールが必要かというと、ページ内移動の際に何らかの動きが無いと、閲覧者は何が起こったかわかりにくいんですね。
いきなりバッとページ最上部やら最下部にやら移動させるよりも、滑らかにページ全体が動く様子を見せることで「ページ内で移動している = ページ遷移ではない」というのがわかりやすいわけです。 専門家の中には「ページ内移動自体するべきではない。」とする方も居て。
その理由は「ページは遷移するのが当たり前だ。していないとなると閲覧者が困惑する。」といった感じ。
困惑させないためのスムーススクロールです。
見た目にかっこいいとかそういうのももちろんありますが、それが第一目的ではありません。

スムーススクロールを実装するにあたり、JSコード内に通常は以下のような記述が含まれます。

a[href^="#"]

緑の #
ハッシュ あるいは フラグメント と読みますが、この記述の意味というのは
id名がついていたら」です。
html5の到達点というのは要素のidで示しますが、id名というのはコードを書いた人間が任意でつけますので特定ができません。
ですから「id名への移動(ページ内移動)がある場合は全て
という形にせざるを得ないんです。
#hoge
かもしれないし、
#top
かもしれないし、
#bottom
かもしれない。それはわかりませんが、以下のようにフラグメントへの移動が示されたら

<a href="#hoge">クリック</a>

スムーススクロールを起動させてください、という意味です。
で、既におわかりの通り、html4時代の開閉プラグインというのは大抵

<a href="#">クリック</a>

こうしてaタグをトリガーにし、必須属性のhrefの値を「空」のつもりで#
これが スムーススクロールの動作条件に含まれてしまう わけです。

対処法

「どうして」の原因がおわかり頂けたと思いますので、今度は「どうするか」の対処について。

スムーススクロール対象を限定的にする

ページTOPやらのボタンなどそもそも要らないんだ、という方はですね、scriptを削除してください。
scriptを削除しても移動自体は行なえます。
行えはしますが、押した瞬間にバっと移動してしまいますので味気ないのと(ry
この処理はテンプレート側で行います。

スムーススクロール対象を限定的にする

テンプレート製作者次第ですが、大抵の場合にはみなさんが記事内で使用できるようにコードが組まれています。

ページ内スクロールの使い方 - カスタマイズ

ページ内スクロール あるいはページ内オブジェクト移動 というのは通常はリンクをクリックすると別ページへジャンプすることになりますが別ページに移動させず 現在開いているページ内で 位置の移動(オブジェクト移動)させることを言いますテンプレートの右下あたりに top へ戻るボタンなどがついている場合がありますよねクリックするとページの最上部に移動しますコンテンツが長文の場合などに一発で上部まで戻れて大変便利です...

正しいhtmlを書きさえすれば記事内でスムーススクロールを利用することが可能です。
JSを書く必要はありません。
「記事内で使うことなんて絶対にない!」と言い切れる方は、対象要素を限定してください。
ページTOPへのスムーススクロールだけが必要ならば

$('a[href^="#"]')
緑の部位を
$('a[href^="#top"]')

と、こんな風に特定id名を入れます。
「#top と書け」という意味ではないですよ。
top の部分は移動対象になるid名を入れてください。
それはテンプレート毎にまちまちですからここで「こう書け」とは言えません。各々ちゃんと調べて入れる、と。
移動対象が複数あるならば

$('a[href^="#abc"],a[href^="#xyz"]')

こうしてカンマ区切りで指定。
この処理はテンプレート側で行います。

対象プラグインをスムーススクロール除外指定

対象プラグインの衝突しているaタグにid名をつけます。
はじめから付いている場合にはそれをそのまま利用します。

例)

<a href="#" title="OPEN" onclick="xxxxx;return false;">クリック</a>

xxxxxの部位は不特定の文字列です。
大体はこんな感じになっているのではないかと思います。
上記内容、現時点ではid名がありませんので追加します。

<a id="hoge" href="#" title="OPEN" onclick="xxxxx;return false;">クリック</a>

この作業はプラグイン側で行います。
その上でテンプレート内のスムーススクロールのコードを

$('a[href^="#"]:not(#hoge)')

こうして除外する。
対象が複数あるのならば

$('a[href^="#"]:not(#hoge):not(#hoge2)')

こうして :not() で繋げます。
id名は 単一 指定しかできませんので対象が複数あるならばそれぞれにid名を付けてください。
idでなくclassにすれば一括指定はできますが、ここでは強制力の強いid名をおすすめします。

この処理はプラグイン側 + テンプレート側 双方の作業です。

まとめ

簡易的な修正は上にまとめた通りです。
私のおすすめはどれかというと、どれも該当しません。
最善策は html5に準拠したものを使う ことです。

関連記事

Comments 0

There are no comments yet.

Leave a reply

テンプレートに関するご質問・不具合のご報告の際はご自身のブログアドレス記載必須です
ご質問の前に必ずお読みください ↓
FC2テンプレート ご利用時のお願い