web-dev-qa-db-ja.com

チェックボックスに対してjQueryクリックイベントハンドラーが2回呼び出されます

ASPXページの次のコードに問題があります。

<script type="text/javascript">
$(document).ready(function() {
    $('.test').click(function() {
        alert("click")
    })
});
</script>

<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />

ブラウザ(FF3.5/IE8)で、次の問題が発生します。

  • チェックボックス(小さな四角)をクリックすると、期待どおりに機能します
  • チェックボックスのテキスト(「チェックボックスXYZ」)をクリックすると、クリックイベントが2回発生し、アラートが2回表示されます。

これは、チェックボックスがHTMLにレンダリングされる方法と関係があると思います。これは次のようになります。

<span class="test">
 <input id="ctl00_c1_cb1" type="checkbox" name="ctl00$c1$cb1" checked="checked"/>
 <label for="ctl00_c1_cb1">Checkbox XYZ</label>
</span>

クリックイベントハンドラーを正しく設定して、2回呼び出されないようにするにはどうすればよいですか?

20
M4N

もう一度質問を読んだ後、それを解決する方法を見つけました。

JQueryセレクターに「入力」を追加するだけです。

<script type="text/javascript">
$(document).ready(function() {
        $('.test input').click(function() {
                alert("click")
        })
});
</script>
8
M4N

同じことを経験したばかりですが、イベントのバブリングが問題の原因であるかどうかはわかりません。カスタムツリーコントロールがあり、アイテムを開くときに、$(id).click()を使用して特定の種類のすべての要素にハンドラーをアタッチします。

これは、すでにイベントが発生している他の場所にある既存のアイテムが、再度追加される可能性があることを意味していると思います。すべてをバインド解除してから再度バインドすると、問題が解決することがわかりました。

$('img.load_expand').unbind("click").click(function()
{
  // handler
});
58
halfer

for属性を持つ<label>は、クリックされたときに関連付けられている<input type="radio">または<input type="checkbox">要素のクリックイベントを発生させるためだと思います。

したがって、jQueryコードでは、<label>内の<input><span class="test">の両方にクリックイベントハンドラーを設定します。 <label>をクリックすると、ラベルに設定したクリックイベントハンドラーが実行され、ラベルが<input>にクリックイベントを発生させると、<input>に設定したクリックイベントハンドラーが実行されます。

20
Russ Cam
$(document).ready(function() {
    $('.test').click(function(event) {
                    event.stopImmediatePropagation();
                    alert("Click");
                    })
                 }
              );

イベントPropagationを停止することで、コードを機能させることができました。チェックボックスのステータス変更には影響しませんでした。

14
Juma

.clickではなく.mouseupを使用するだけです

3
yoshyosh

あなたが見ているのはイベントバブリングです。クリックイベントは最初にラベルによって処理され、次にチェックボックスに渡されます。それぞれに1つのアラートが表示されます。イベントのバブリングを防ぐには、クリックハンドラーでfalseを返す必要があります。

$(document).ready(function() {
        $('.test').click(function() {
                alert("Click");
                return false;
        })
});

ただし、これによりイベントのバブリングが防止されますが、チェックボックスの状態が変更されないという望ましくない副作用もあります。したがって、その周りをコーディングする必要があります。

2
Andrew

解決済み:これはFirefox3.6.12およびIE8で動作します。

_$(function(){
        $("form input:checkbox").unbind("click")
        .click(function(){
            val = $(this).val();
            alert(val);
        })
    }
_

秘訣は、unbind("click").にバインドする前に.click(fn)することです。これにより、同じイベントが2回発生することが無効になります。

チェックボックスが最初にチェックされたとき、イベント「変更」はだまされないことに注意してください。そのため、代わりに「クリック」を使用します。

2
aifarfa

クリックイベントで同じ問題が発生し、 this の記事が見つかりました。本質的に、<body></body>タグ内に複数のjQueryドキュメント対応関数がある場合、複数のイベントを取得できます。もちろん、修正は、上記のように、それを行わないか、クリックイベントのバインドを解除して再バインドすることです。複数のjavascriptライブラリがある場合、複数のdocument.ready()を回避するのが難しい場合があるため、バインド解除は適切な回避策です。

<code>
$('#my-div-id').unbind("click").click(function()
  {
    alert('only click once!');
  }
</code>
1
MontyThreeCard

質問はもう終わりですが、同じ問題に直面したばかりで、見つけた解決策を追加したいと思います。将来、同様の問題に役立つ可能性があります。

ASPコードのように:を追加すると

_<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />
_

問題は、_<asp:CheckBox ...>_がhtmlコントロールではなく、単なる何かであるということですASP いくつかのサイコのねじれた心から構成されています 発明されたので、ブラウザは何か他のものを受け取ります。

ブラウザは次のようなものを受け取ります:

_<span class="test">
    <input id="garbageforYourId_cb1" type="checkbox" name="garbage$moregarbage$cb1"/>
    <label for="evenMoreGarbage_cb1">Checkbox XYZ</label>
</span>
_

考えられる多くの解決策の1つ:

ブラウザは、入力「チェックボックス」とそのテキストのラベルを含むスパンを受け取ります。したがって、これに対する私の解決策は次のようになります。

_$('.test > :checkbox').click(function() {
    if ($(this).attr("checked")) {
        alert("checked!!!");
    } else {
        alert("non checked!!!");
    }
});
_

そこで何が起こったのですか?このセレクター$('.test > :checkbox')は、クラス「test」の要素を見つけて、それに含まれるチェックボックスを表示することを意味します。

1
Oaxas

関数は2回実行されます。一度内側から、それからそれはそれ自身の内側から再び呼び出されます。最後にreturnステートメントを追加するだけです。

<script type="text/javascript">
$(document).ready(function() {
    $('.test').click(function() {
        alert("click");
        return false;
    })
});
</script>

<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />

これは私にとって完璧に機能しました。

0
Kalob Taulien