jQuery父子元素单击事件

时间:2012-02-12 02:36:50

标签: jquery input click parent-child stoppropagation

我的HTML看起来像这样(不幸的是它无法更改,因为它是使用我正在使用的CMS呈现的):

<li>
<input id="cb1" type="checkbox">
<label for="cb1">
<div>Some Other Content</div>
<div class="pledge">Click to Pledge</div>
</label>
</li>

jQuery。

$("div.pledge").click(function() {

  var checkboxlabel = $(this).parent("label");

  $("input[for=checkboxlabel]").attr('checked', !$checkbox.attr('checked'));

});

如果我点击标签内的任何位置,使用此代码将切换复选框。我需要的是仅在单击<div class="pledge">元素时才执行操作。我怀疑.stopPropagation();将在这里帮助我,但我无法让它正常工作。

这是另一个似乎正在实现同样想法的镜头:

$("div.pledge").click(function() {

  $("input[for=' + this.parent("label").attr("id") + ']").attr('checked', !$checkbox.attr('checked'));

});

5 个答案:

答案 0 :(得分:4)

在各行之间阅读,在我看来,如果没有任何JS,以下内容将达到您想要的结果:

<li>
<input id="cb1" type="checkbox">
<div>
<div>Some Other Content</div>
<label for="cb1">Click to Pledge</label>
</div>
</li>

http://jsfiddle.net/nnnnnn/VqmBb/

这会在复选框旁边显示“其他内容”和“点击承诺”,但正如您在演示中看到的那样,只有“点击承诺”部分会在点击时选中/取消选中该框。

我已经交换了你的标签和“承诺”div,并利用标签的for属性将其与复选框关联,以便它自动检查/取消选中它。 (虽然现在外部div实际上并没有做任何事情,除非你需要它来造型,否则可以删除。)

关于您的JS,以下行存在一些问题:

$("input[for=checkboxlabel]").attr('checked', !$checkbox.attr('checked'));

首先,您的选择器"input[for=checkboxlabel]"似乎正在尝试使用之前在该行上声明的checkboxlabel变量,但您实际完成的只是包含恰好包含文本的字符串“ checkboxlabel”。因此,您不会选择html中的任何元素,因为您没有“input”元素,其“for”属性等于字符串“checkboxlabel”。你也有一个未在任何地方定义的变量$checkbox

更新:好的,以下内容适用于您更新的html(适用于我)。除了您尝试使用未声明的变量$checkbox之外,现有JS代码的问题在于您尝试将单击处理程序绑定到“承诺”div。意味着您没有做任何事情来处理标签其他部分的点击。鉴于您特别想要停止对标签其他部分的点击,我建议您将.click()处理程序附加到标签 - 标签的子项上的点击将冒泡到标签的单击处理程序,然后您可以测试单击的元素是否为具有“pledge”类的元素。如果没有返回false取消标签点击的默认行为,但如果 ,则“pledge”元素不执行任何操作并让默认设置发生:

$("div.pledge").parent("label").click(function(e) {
    if (!$(e.target).hasClass("pledge"))
        return false;
});

(注意我选择“div.pledge”的父级而不是仅仅说$("label").click(),以便此处理不会附加到所有标签。)

如果你不喜欢,我认为mgibsonbr的答案是个不错的选择。

答案 1 :(得分:1)

如果我理解正确,当您说“您无法更改HTML”时,您只是指服务器生成的HTML,对吗?但是你可以使用JavaScript在客户端进行更改吗?

jQuery(document).ready(function($) {
    $('label[for="cb1"]').removeAttr("for");
    $("div.pledge").click(function() {
        $(this).parent().prev().attr("checked", function(index,oldValue) {
            return !oldValue;
        });
    });
});

这样标签就不再有for了,手动处理div点击。

答案 2 :(得分:0)

您的代码,HTML和JavaScript均无效 <label>是一个inline元素,其内部不能包含block元素,例如<div>。 然后,你的JS代码缺少一些;(我看到你添加了它们)。此外,这没有任何意义:

$("input[for=checkboxlabel]").attr('checked', !$checkbox.attr('checked'))

这应该有效。请注意新的html标记和正确的jQuery代码:

<强> HTML:

<li>
    <label>Something that describes this checkbox</label>
    <input id="check" type="checkbox">
    <p>Some Other Content</p>
    <a href="#" id="pledge">Click to Pledge</a>
</li>

<强> JQ:

$('#pledge').click(function()}{ $('#check').prop('checked', true); });

答案 3 :(得分:0)

您没有以正确的方式进行此操作 - 您需要在标签中指定'for'属性,并将其设置为您指定的复选框的ID,如下所示:

<label for="checkbox_id">Label-text</label>
<input type="checkbox" id="checkbox_id" />

单击标签时,将选中/取消选中该复选框。 @elclanrs上面提出的所有观点也都有,html和js无效。

答案 4 :(得分:0)

在标签元素内移动复选框。 inputlabel元素不需要任何js甚至id或for属性。试试这个。

<label>
    <input type="checkbox" />
    <div>Some Other Content</div>
    <div class="pledge">Click to Pledge</div>
</label>

<强> Demo