クリックファンクションがうまくいきません。

投稿者: Anonymous

class="link-block"のついたliつまりリストをクリックした時、.removeClass('active');activeというクラスを削除するようにしたかったのですが、

なぜかリストをクリックしても反応せずに削除されません。

id="maware"liだけは、反応して削除されます。

CSSにとしてもだめでした。どうもclass="link-block"のついたリストをクリックできていないのかと思っているのですが、上下の順番でクリックできていないのでしょうか?

.link-block {
  display: block;
  z-index: 99999;
}

・ソースコード

<!-- drawermenu -->
<!-- drawermenu-button -->
<div class="modal-button-wrap">
  <a class="animation-hover action-hover modal-button-wrap__button">
    <span class="modal-button-wrap__border"></span>
    <!-- border -->
    <span class="modal-button-wrap__border"></span>
    <!-- border -->
    <span class="modal-button-wrap__border"></span>
    <!-- border -->
  </a>
</div>

<!-- drawermenu -->
<nav>
  <div id="nav__drawermenu-wrap">
    <ul>
      <li id="maware"><a class="link-block" href="#js-about-me">ABOUTME</a></li>
      <li><a class="link-block" href="#js-about-me"><span class="gotootherpage"><img class="top-gnav__link-sixth__goto-other-page" src="img/common-img/goto-other-page.svg" alt="goto-other-page-image"></span>ABOUTME</a></li>
      <li><a class="link-block" href="#js-gallary">GALLARY</a></li>
      <li><a class="link-block" href="#js-gmap">MAP</a></li>
      <li><a class="link-block" href="#js-contact">CONTACT</a></li>
      <li><a class="link-block" href="http:///index.html">TOP</a></li>
      <li><a class="link-block" href="http:///index.html">BLOG</a></li>
    </ul>
  </div>
</nav>
<!-- /drawermenu -->

・JS

$(function() {
  $('.kuruttosuru').on('click', function() {
    $(this).addClass('active');
    return false;
  });
});
<!-- drawermenu-button-three-whiteline-クリックした際にクルット回るアクション -->
<script>
  $(function() {
    $('.modal-button-wrap__button, .link-block').on('click', function() {
      $(this).removeClass('active');
      return false;
    });
  });
</script>

・下記のJSがあると、うまくいかず下記をコメントアウトするとうまくいきます。
下記に何かおかしくなる要素があるのでしょうか?

<!-- ページ内遷移 -->
<script>
  $(function() {
    // #で始まるアンカーすべてをクリックした場合に処理
    $('a[href^=#]').click(function() {
      // スクロールの速度
      var speed = 1000; // ミリ秒
      // アンカーの値取得
      var href = $(this).attr("href");
      // 移動先を取得
      var target = $(href == "#" || href == "" ? 'html' : href);
      // 移動先を数値で取得
      var position = target.offset().top;
      // スムーススクロール
      $('body,html').animate({
        scrollTop: position
      }, speed, 'swing');
      return false;
    });
  });
</script>

https://jsfiddle.net/80od313c/

上記に再現しましたが、こちらは実際にJSを動かすことはできないのですかね?

解決

大元の疑問と思われる以下の点についてのみお答えします。

class="link-block" のついた li つまりリストをクリックした時、.removeClass('active');active というクラスを削除するようにしたかったのですが、なぜかリストをクリックしても反応せずに削除されません。id=”maware”のliだけは、反応して削除されます。

下の「スニペットを実行」をクリックして、現れた3つのリンクをクリックしてみてください。.link-block#hoge が指定された最後のリンクは2つのアラートが表示されそうですが、片方しか表示されません。

_x000D_

_x000D_

$(function() {_x000D_
  $('.link-block').on('click', function() {_x000D_
    alert('link-block clicked!')_x000D_
    return false;_x000D_
  });_x000D_
  $('a[href^="#"]').click(function() {_x000D_
    alert('a[href^="#"] clicked!')_x000D_
    return false;_x000D_
  });_x000D_
});

_x000D_

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<ul>_x000D_
  <li><a href="#hoge">href</a></li>_x000D_
  <li class="link-block"><a href="">class</a></li>_x000D_
  <li class="link-block"><a href="#hoge">class+href</a></li>_x000D_
</ul>

_x000D_

_x000D_

_x000D_

この原因は return false; にあります。

上の2番目のリンクでは <a> をクリックしたにも関わらず <li> のclickイベントハンドラが呼び出されていますよね。これは親要素にイベントが伝播される「イベントのバブリング」という仕様によるものです。

あなたはリンクをクリックしてもページ遷移が起きないように return false; を書いたのだと思いますが、この記述はイベントのバブリングも止めてしまいます。そのため、

  1. ユーザーがリンクをクリックした
  2. まず a[href^="#"] に設定されたイベントハンドラが呼び出される
  3. このイベントハンドラは return false; しているので、ここでバブリングが止まる
  4. <li> にイベントが伝播しないので、.link-blockに対するイベントハンドラも実行されない

という動きになってしまっています。

ブラウザデフォルトの挙動は抑制しつつバブリングは残したい、という場合には、イベントハンドラに引数として渡される Event オブジェクトの preventDefault() を呼び出します。

_x000D_

_x000D_

$(function() {_x000D_
  $('.link-block').on('click', function(e) {_x000D_
    alert('link-block clicked!')_x000D_
    e.preventDefault();_x000D_
  });_x000D_
  $('a[href^="#"]').click(function(e) {_x000D_
    alert('a[href^="#"] clicked!')_x000D_
    e.preventDefault();_x000D_
  });_x000D_
});

_x000D_

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<ul>_x000D_
  <li><a href="#hoge">href</a></li>_x000D_
  <li class="link-block"><a href="">class</a></li>_x000D_
  <li class="link-block"><a href="#hoge">class+href</a></li>_x000D_
</ul>

_x000D_

_x000D_

_x000D_

逆に、イベントの伝播のみ抑制するには stopPropagation() を使います。jQuery経由で設定したイベントハンドラで return false; すると prependDefault()stopPropagation() の両方が実行される、ということになります。

参考

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *