質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

ページ内アンカーリンクでアコーディオンを開きたい

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 486

okama

score 22

ページ内のアンカーリンク(href="#article")をクリックすると
[id="article"]に移動し、アコーディオンが開くという動きを実装したいです。
(アコーディオンが先でもアンカーが先でも大丈夫です!)

アコーディオン部分はアンカーでも開くし、アコーディオン自体のクリックでも開くようにしたいです。
開閉をわかりやすくしたのでアコーディオン右には画像で+/-もつけています。

ページ内に他にもアンカーリンクを利用するため
ユニークな記述をお願いします。

下記の記述でアコーディオンだけの開閉は問題ありませんが
アンカーを押してもアコーディオンが開きませんでした。

どこの記述が問題ありますでしょうか。。

html

<div class="fee_inner01">
 <div class="fee_article_top">
  <ul>
   <li>*1<a href="#article" id="article-anc_01" class="fee_article_btn">見出し01</a></li>
   <li>*2 <a href="#article" id="article-anc_02" class="fee_article_btn">見出し02</a></li>
   <li>*3 <a href="#article" id="article-anc_03" class="fee_article_btn">見出し03</a></li>
  </ul>
 </div>
 <div class="fee_article fee_article mgb-20">
  <div class="fee_article_title ac_btn" id="article">注意事項</div>
  <div class="accordion_in">
   <p>*1 テキストが入ります</p>
   <p>*2 テキストが入ります</p>
   <p>*3 テキストが入ります</p>
  </div>
 </div>
</div>

css

.fee_article_top ul {
    padding: 12px;
    margin: 15px 0 20px;
    position: relative;
}
.fee_article_in {
    padding: 0 5% 20px;
}
.ac_btn {
    position: relative;
}
.ac_btn::after {
    content: "";
    display: inline-block;
    width: 18px;
    height: 18px;
    background: url(../images/ac_plus.png) no-repeat;
    background-size: 18px;
    position: absolute;
    right: 20px;
    top: 16px;
}
.ac_btn.open::after {
    content: "";
    display: inline-block;
    width: 18px;
    height: 18px;
    background: url(../images/ac_minus.png) no-repeat;
    background-size: 18px;
    position: absolute;
    right: 20px;
    top: 16px;
}

js

$(function () {
  $(".fee_article_title").click(function () {
    $(this).toggleClass("open").next().slideToggle("normal");
  });
});

$(function () {
  $('.fee_article_in').css("display", "none");
  $('.fee_inner01 a[href^="#"]').click(function () {
        $(".fee_article_title").addClass("open");
    $(".fee_article_in").css("display", "block");
    var speed02 = 500;
    var href02 = $(this).attr("href");
    var target02 = $(href02 == "#" || href02 == "" ? 'html' : href02);
    var position02 = target02.offset().top;
    $("html, body").animate({
      scrollTop: position02
    }, speed02, "swing");
    return false;
  });
});
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

0

リンクをクリックした時にURLに#articleが付与されます。

URLから#articleが取得できる関数があるので該当するアコーディオンメニューを開く様にJSファイルにて関数を追記すればOKだと思います。

実行タイミングとしては、クリックイベント時と初期リロード時です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/20 19:35

    一部変更してローカルで正常に確認できましたが
    やはり実際に商用にアップしクリックすると一度ページがリロードされてしまい、URLの後ろに#articleがつくだけでアコーディオンが開かれませんでした。。

    色々とご提案いただいたのにすみません><


    念のため、下記修正後のものです。
    ▼HTML
    <div class="fee_inner01">
    <div class="fee_article_top">
    <ul>
    <li>*1<a href="#article" id="article-anc_01" class="fee_article_btn">見出し01</a></li>
    <li>*2 <a href="#article" id="article-anc_02" class="fee_article_btn">見出し02</a></li>
    <li>*3 <a href="#article" id="article-anc_03" class="fee_article_btn">見出し03</a></li>
    </ul>
    </div>
    <div class="fee_article fee_article mgb-20">
    <div id="article" class="notification js-toggle">
    <div class="fee_article_title ac_btn">注意事項</div>
    <div class="fee_article_in js-toggleContents">
    <p>*1 テキストが入ります</p>
    <p>*2 テキストが入ります</p>
    <p>*3 テキストが入ります</p>
    </div>
    </div>
    </div>
    </div>


    ▼JS

    $(function () {
    // 通常クリック時
    $('.js-toggle').on('click', function () {
    $('.js-toggleContents').slideToggle();
    });

    // ページ内遷移時
    $('a[href^="#"]').click(function () {
    var speed = 500;
    var href = $(this).attr("href");

    // articleがクリックされた場合は、対象の要素を開いた状態にする
    if (href === "#article") {
    $('.js-toggleContents').show();
    }
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    $("html, body").animate({
    scrollTop: position
    }, speed, "swing");
    return false;
    });
    });

    キャンセル

  • 2020/07/20 20:42

    ページ内リンクの指定を、[ページパス/アンカーリンク]にするとどうでしょうか?

    <a href=/hoge/#article" id="article-anc_01" class="fee_article_btn">見出し01</a>

    キャンセル

  • 2020/07/21 10:47

    試してみます!

    キャンセル

0

jqueryはよくわからないので素のJavascriptで再現してみました。
面倒くさいので全部HTMLに書き込んでいるため、コピペするだけで動きます。
ソースコード

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="robots" content="noindex,nofollow" />
    <title>homePage</title>
    <style>
        ul {
            margin: 0px 0 10px 0;
            padding: 0;
            list-style: none;
        }

        li {
            display: block;

        }

        a {
            cursor: pointer;
        }

        .wrapAccordion {
            position: relative;
            width: 200px;
            height: 70px;
        }

        .accordion {
            position: absolute;
            overflow: hidden;
            height: 0;
            margin: 0;
            padding: 0;
        }

        .show {
            animation: toggle 0.3s both;

        }

        .hide {
            animation: toggle 0.3s both reverse;
        }

        button {
            width: 20px;
            height: 20px;
            line-height: 0;
            margin: 0;
            padding: 0;
            font-size: 20px;
        }

        @keyframes toggle {
            0% {
                height: 0;
            }

            25% {
                height: 25%;
            }

            50% {
                height: 50%;
            }

            75% {
                height: 75%;
            }

            100% {
                height: 100%;
            }
        }
    </style>

</head>
<body>
    <ul>
        <li>*1 <a href="#article">見出し01</a></li>
        <li>*2 <a href="#article">見出し02</a></li>
        <li>*3 <a href="#article">見出し03</a></li>
    </ul>
    <strong id="alert">注意事項</strong>
    <button type="button">+</button>
    <div class="wrapAccordion">
        <ul id="accordionJs" class="accordion">
            <li>*1 テキストが入ります</li>
            <li>*2 テキストが入ります</li>
            <li>*3 テキストが入ります</li>
        </ul>
    </div>
    <script>
        const accordion = document.getElementById("accordionJs");
        const clickBtn = (btn) => {
            btn.addEventListener("click", () => {
                if (accordion.clientHeight == 0) {
                    accordion.classList.remove("hide");
                    accordion.style.height = "0";
                    setTimeout(() => {
                        accordion.classList.add("show");
                    }, 200);
                } else {
                    accordion.classList.remove("show");
                    accordion.style.height = "100%";
                    setTimeout(() => {
                        accordion.classList.add("hide");
                    }, 200);
                }
            });
        }

        const button = document.getElementsByTagName("button")[0];
        const a0 = document.getElementsByTagName("a")[0];
        const a1 = document.getElementsByTagName("a")[1];
        const a2 = document.getElementsByTagName("a")[2];
        clickBtn(button);
        clickBtn(a0);
        clickBtn(a1);
        clickBtn(a2);
    </script>
</body>
</html>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/21 10:49

    コメントいただきありがとうございます。

    普段書いたことのない記述なため理解の乏しく申し訳ないのですが、
    アンカーリンクをクリックした際、+ボタンの画像が-ボタンになるようcssで記述しておりました。
    それは可能でしょうか?

    アンカーリンクをクリックした際はアコーディオンは開く動作のみで
    閉じる動作はアコーディオン自体のクリック時のみの動作にしたいのですが可能でしょうか。。

    キャンセル

  • 2020/07/21 13:37

    可能です。下の回答のコードを先日と同様にそのままhtmlファイルにペーストしたら
    動作するようにしてあります。

    キャンセル

0

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex,nofollow" />
  <title>homePage</title>
  <style>
    ul {
      margin: 0px 0 10px 0;
      padding: 0;
      list-style: none;
    }

    li {
      display: block;

    }

    strong {
      padding: 0;
      margin: 0;
      font-size: 20px;
      display: inline-block;
      vertical-align: top;
      line-height: 1;
    }

    a {
      cursor: pointer;
    }

    /*overflow:hiddenを設定することで高さが変われば*/
    /*はみ出したリスト部分は表示されなくなる*/
    .accordion {
      position: absolute;
      overflow: hidden;
      height: 0;
      margin: 0;
      padding: 0;
    }

    /*toggleアニメを0%から実施し終了後もスタイルは変わらない*/
    /*アニメーションにかかる時間は0.3秒*/
    .open {
      animation: toggle 0.3s forwards;
    }

    /*toggleアニメを100%から実施し終了後もスタイルは変わらない*/
    /*アニメーションにかかる時間は0.3秒*/
    .close {
      animation: toggle 0.3s forwards reverse;
    }

    /*高さを徐々に変更するアニメーション*/
    @keyframes toggle {
      0% {
        height: 0;
      }

      25% {
        height: 17.5px;
      }

      50% {
        height: 35px;
      }

      75% {
        height: 62.5px;
      }

      100% {
        height: 70px;
      }
    }

    button {
      width: 20px;
      height: 20px;
      border: none;
      cursor: pointer;
      display: inline-block;
      vertical-align: top;
      line-height: 0;
      outline: none;
      padding: 0;
      appearance: none;
      background-color: transparent;
      background-size: cover;
      background-position: center;
    }

    .plus {
      background-image: url(https://f.easyuploader.app/eu-prd/upload/20200721115155_393966734648496e6465.png);
    }

    .minus {
      background-image: url(https://f.easyuploader.app/eu-prd/upload/20200721115155_416d3465584d65733531.png);
    }
  </style>

</head>

<body>
  <ul>
    <li>*1 <a href="#article">見出し01</a></li>
    <li>*2 <a href="#article">見出し02</a></li>
    <li>*3 <a href="#article">見出し03</a></li>
  </ul>
  <strong id="alert">注意事項</strong>
  <button id="button" class="plus" type="button"></button>
  <ul id="accordionJs" class="accordion">
    <li>*1 テキストが入ります</li>
    <li>*2 テキストが入ります</li>
    <li>*3 テキストが入ります</li>
  </ul>
  <script>
    // アコーディオンとして開閉するulタグを定義
    const accordion = document.getElementById("accordionJs");

    // アコーディオンが開く時に実行する関数を定義
    const open = () => {
      // アコーディオンのクラスにcloseが含まれていれば削除
      if (accordion.classList.contains("close")) {
        accordion.classList.remove("close");
      }
      // アコーディオンの高さを0にする
      accordion.style.height = "0";
      // 200ミリ秒後に
      setTimeout(() => {
        // ボタンの背景をマイナスにし
        button.classList.add("minus");
        // 開くときのcssアニメーションを実行するためopenクラスを付与。
        accordion.classList.add("open");
      }, 200);
    }

    // アコーディオンが閉まる時に実行する関数を定義
    const close = () => {
      // 閉めるときはopenクラスが確定で存在するため削除
      accordion.classList.remove("open");
      // アコーディオンの高さを70pxにする
      accordion.style.height = "70px";
      // 200ミリ秒後に
      setTimeout(() => {
        // ボタンの背景をプラスにし
        button.classList.remove("minus");
        // 閉じるときのcssアニメーションを実行するためcloseクラスを付与。
        accordion.classList.add("close");
      }, 200);
    }
    // ボタンをクリックしたときの動作を関数として定義
    const clickBtn = (btn) => {
      //ボタンをクリックした場合
      btn.addEventListener("click", () => {
        //アコーディオンの高さが0ならば 上で定義したopen関数を違うのであればclose関数を実施
        accordion.clientHeight == 0 ? open() : close();
      });
    }
    // アコーディオン開閉ボタンを定義
    const button = document.getElementById("button");
    // 引数としてbuttonを渡し上で定義したclickBtn関数を実行
    clickBtn(button);
    // 各aタグをクリックした時に実行する関数
    const clickA = (a) => {
      //各aタグをクリックした場合
      a.addEventListener("click", () => {
        //アコーディオンの高さが0であるならば
        if (accordion.clientHeight == 0) {
          //上記で定義したopen関数を実行
          open();
        }
      })
    }

    //0番目のaタグを定義
    const a0 = document.getElementsByTagName("a")[0];
    //1番目のaタグを定義
    const a1 = document.getElementsByTagName("a")[1];
    //2番目のaタグを定義
    const a2 = document.getElementsByTagName("a")[2];

    //引数としてa0を渡し上で定義したclickA関数を実行
    clickA(a0);
    //引数としてa1を渡し上で定義したclickA関数を実行
    clickA(a1);
    //引数としてa2を渡し上で定義したclickA関数を実行
    clickA(a2);

  </script>
</body>

</html>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/24 21:35

    追記いただきありがとうございました。

    これで書き換えて試してみますm(><)m

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る