LoginSignup
5
5

More than 5 years have passed since last update.

IDが重複してもページ内ジャンプできるようにする方法

Last updated at Posted at 2015-12-22

HTML上に複数の同じようなコンテンツを置かざるを得ないケースに遭遇することってたまにあると思います。

たとえば

  • PCとスマホのコンテンツを同一ページ別DOMで用意するとき
  • 多言語のコンテンツを同一ページに複数DOMで用意するとき
  • テンプレートを作って中身を変えずにクローンしまくるとき

本来サーバーサイドで出し分けるべきものの場合が多いですが、
訳あってフロントサイドしか触れないなど、やむを得ないケースはあるかと思われます。

そして、何かの手違いだったりやむを得ない事情で、IDも一緒にコピーしてしまうことがあるかと思われます。
要素のIDは重複してはならないのがルールですが、
実はCSSやJavaScriptではある程度許容されているような動作をします(おそらく仕様にない挙動ですので濫用はしないように)。

複数IDのフィルタリング

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>has duplicated</title>
  <style>
.env-1 {
  display: none;
}
  </style>
</head>
<body>
  <a href="#p1"></a>
  <a href="#p2"></a>
  <div class="env-1">
    <p id="p1">この親のdivはPCだとか。</p>
    <p id="p2">この親のdivはenだとか。</p>
  </div>
  <div class="env-2">
    <p id="p1">この親のdivはSPだとか。</p>
    <p id="p2">この親のdivはjaだとか</p>
  </div>

  <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
</body>
</html>

このHTMLの2番目の<p id="p1">を取得する方法をいくつか。(※要jQuery)

↓こういうのは無理です。

$('.env-2#p')

↓これなら大丈夫みたいです。

$('.env-2').find('#p2');

↓これなら大丈夫(重複しているIDの2番目)

$('[id="p2"]').eq(1)

↓これでも大丈夫(重複しているIDの最後)

$('[id="p2"]').eq(-1)

↓これが実用的(DOMの可視/不可視をまるごと切り替えてるとき)

$('[id="p2"]:visible')

ページ内ジャンプの実装

最後の:visibleセレクタを用い、見えている方のIDの元へ飛んでいってくれるページ内ジャンプを書いてみました。

internal_link_with_duplicate_id.js
$('a[href^=#]').on('click', function() {
    var targetId = $(this).attr('href').slice(1);
    var selector = targetId ? '[id="' + targetId + '"]:visible' : 'html';
    var $target = $(selector);

    var dist = $target.offset().top;

    $('html, body').animate({scrollTop: dist});
});

デモ:
ID重複ページ内リンク - jsdo.it

補足

このように、属性セレクタ等を用いて重複したIDを取得できることがわかりましたが、
重ね重ねIDの重複はHTMLとしてはinvalidのため、出来る限り別IDにするか、クラスやデータ属性を使って回避しましょう。
(僕は基本的に実務でのIDの使用は極力避けてます。)

ちなみに、IDの重複チェッカーを作ったので、Validatorに通す前に軽くチェックするフローを挟むなど活用して頂ければ幸いです。
JavaScript - DOM上のIDの重複を検出する - Qiita

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5