web-dev-qa-db-ja.com

jQueryでonclickアクションを防止する

onclickイベントアクションのリンクがいくつかあります

<a href="#" onclick="alert('panic!')">Let's panic</a>
<a href="#" onclick="alert('panic!')" disabled="disabled">I can't panic no more</a>

Onclickアクションを削除せずに、disabled属性を使用してリンクでのイベントアクションの実行を防止する必要があります。

$('a[disabled]').click(function(e){
  e.stopPropagation();
  return false;
});

このコードは役に立ちません。

更新このコードでも動作しません

<html><head><script type='text/javascript' src='jquery-1.3.2.js'></script></head>
<body>
<a href='#' onclick="alert('HA-ha!')" disabled="disabled" class="disabled">TEST</a>
<script type="text/javascript">
    $('a[disabled], a.disabled').click(function(e){
        console.log('override?');
        e.stopImmediatePropagation();           
            e.preventDefault();
        e.stopPropagation();
        return false;       
    });
</script>
</body></html>
30
Andrew Rumm

jQueryはこの1つのOOTBを解決しません。それは助けにはなりますが、stopPropagationstopImmediatePropagationpreventDefault、_return false_はどれも、単に要素にアタッチしただけでは機能しません。要素のクリックハンドラをオーバーライドする必要があります。

ただし、「onclickアクションを削除せずに」」と記述します。そのため、イベントがトリガーされた時点でデフォルトの動作をオーバーライドする必要があります(無効なアンカーのnull属性を単純にonclickingするよりクリーンなアプローチとは対照的に):

ここに私が意味するものがあります:

_<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<title>Disable clicks</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
  <a href="#" onclick="alert('panic!')">Let's panic</a>
  <a href="#" onclick="alert('panic!')" disabled="disabled">I can't panic no more</a>

  <script>
  $('a[onclick]').each(function(){
    $(this).data('onclick', this.onclick);

    this.onclick = function(event) {
      if($(this).attr('disabled')) { // HERE
        return false;
      };

      $(this).data('onclick').call(this, event || window.event);
    };
  });
  </script>
</body>
</html>
_

デモはこちら

そこでのアプローチは、アンカーが「無効」になっている場合とthenをキャッチするために、インラインクリックハンドラー(onclick)をプリエンプティブロジックでオーバーライドすることです。 -)イベントをキャンセルします(_return false_を使用)。

ここでの利点は、アンカーを再び有効にするには、単に.removeAttr('disabled')するだけです。

54
Crescent Fresh

disabledはアンカーのプロパティではありません。代わりにrel='disabled'などを使用してください。

$('a[rel="disabled"]').click( function() { return false; } );

更新

ああ、もちろん。それは実際にマークアップでインラインであるため、alertを起動します!私はそれを決してしないので気づかなかった。そのクリックハンドラーをマークアップから取り出して、最初にjQueryで実行すると、次のようなことができます。

$('a').click( function() {
  if( $(this).attr('rel') == 'disabled' ) { return; }
  // do stuff here when not disabled
  return false; // so your '#' href doesn't get used
} );
7
rfunduk

問題は、jQueryがイベントを順番に追加することです。他のイベントを停止するには、停止する必要があるイベントが来る必要がありますafter停止コード。 on clickにコードがあるため、順序を変更する必要があります。これは私がすることです:

_<a href='#' onclick="alert('HA-ha!')" class="disabled">TEST</a>
<a href='#' onclick="alert('HA-ha!')">TEST</a>
<script type="text/javascript">
    $('a').each(function(){
        // Cache event
        var existing_event = this.onclick;

        // Remove the event from the link
        this.onclick = null;

        // Add a check in for the class disabled
        $(this).click(function(e){ 
            if($(this).hasClass('disabled')){
                e.stopImmediatePropagation();
                e.preventDefault();
            }                
        });

        // Reattach your original onclick, but now in the correct order
        // if it was set in the first place
        if(existing_event) $(this).click(existing_event);
    });
</script>
_

利点は、jQueryを使用して無効なクラスを削除/追加するだけです:$('a#whatever').addClass('disabled')または削除$('a#whatever').removeClass('disabled')し、他のクリーンアップ/セットアップは不要です。

5
Doug Neiner

JQueryによって追加されたクリックハンドラーは、マークアップで追加されたクリックハンドラーの後に起動するようです。私の解決策は、マークアップではなくjQueryを使用してクリックハンドラーを適用することですが、これを行うためのコードを十分に制御できない可能性があります。その場合、クラスが無効になっているアンカータグにクリックハンドラーを適用しないでください(そして、はい、不適切な属性ではなくクラスを使用します)。マークアップを制御できない場合は、jQueryを使用してクリックハンドラーを置き換え、後で再適用するために保存することをお勧めします。

   $(function() {
      $('a.disabled').each( function() {
         var $this = $(this);
         var click = $this.attr('onclick');
         if (click) {
             $this.data('click',click);
             // add return false to prevent default action
             $this[0].onclick =  function() { return false; };
         }
      });

      $('#restoreClick').click( function() {
          $('a.disabled').each( function() {
              var $this = $(this);
              $this.removeClass('disabled');
              var click = $this.data('click');
              if (click) {
                  $this[0].onclick = click;
              }
          });
      });
   });

テスト済み:

<div>
    <a href="#" onclick="alert('panic!')">Let's panic</a>
    <a href="#" onclick="alert('panic!')" class="disabled">I can't panic no more</a>
</div>
<div>
    <input type="button" id="restoreClick" value="Restore" />
</div>
1
tvanfosson

今日、onclicksを防ぐための非常に簡単なソリューションを見つけましたが、必要な場合はアクションを維持します。

<a href="javascript:alert('panic!')" >Let's panic</a>
<a href="javascript:alert('panic!')" disabled="disabled">I can't panic no more</a>

$('a').click(function(e){
    if($(this).attr('disabled')) e.preventDefault();
});

私は「javascript:」を使用することは大したファンではありませんが、これはこの問題に対する最も簡単な解決策でした。

それが役に立てば幸い!

0
MrBojangles