为什么 .attr('checked','checked') 不起作用?

4

我有以下的代码片段(使用了jQuery 1.4.2):

$.post('/Ads/GetAdStatsRow/', { 'ad_id': id }, function(result) {
    $('#edit_ads_form tbody').prepend(result);
    $(result).find('td.select-ad input').attr('checked','checked').click();
});

假设该帖子正常工作并返回一个正确的预构建 <tr>,其中包含一些 <td>。这里有一个奇怪的问题: $(result).find() 行可以找到正确的输入框(因为它是单元格中唯一的输入框),并且可以正确地运行链接的 click() 函数,但它拒绝将复选框设置为已选中,而我需要这样做。
还有一个疯狂的转折...当我变得非常具体,并将 $(result).find() 行更改为此内容(即复选框的 id)时:
$('#ad_' + id).click();

它勾选了复选框,但没有运行click()函数!如果我设置为

$('#ad_' + id).attr('checked','checked').click();

它会像复选框被选中一样运行点击函数,但是复选框仍然未被选中,如果我执行

$('#ad_' + id).click().attr('checked','checked');

它根本没有做任何事情。

这到底是怎么回事?我快被搞疯了……

谢谢!

编辑

这是我在 $(function()) 调用中设置点击事件的方法:

$('td.select-ad input').live('click',AdPreview.selectAd);

对于所有其他复选框,它们按原样工作,如果手动单击,则新添加的复选框确实有效。

编辑2

经过一些挖掘,我发现这个:

$('#ad_' + id).click();

实际上,在检查复选框的同时,确实会调用我的点击函数。 但是,当调用点击函数时(我已经检查过input是正确的复选框),

var input = $(this);
console.log(input.is(':checked'));

日志返回false,即使实际上已经勾选了该框! GAH WTF


你能展示一下你是如何定义点击事件处理器以及它的功能吗?你是如何测试“点击函数是否被执行”的呢?你说的是触发点击事件,对吗? - Ates Goral
5个回答

4
我认为这是因为你正在对一些不在DOM中的HTML进行查找。
$.post('/Ads/GetAdStatsRow/', { 'ad_id': id }, function(result) {
    // the "result" html is copied into the DOM
    $('#edit_ads_form tbody').prepend(result);

    // now you're doing a find on some HTML which isn't in the DOM.
    $(result).find('td.select-ad input').attr('checked','checked').click();
});

这就解释了为什么做特定的事情在某种程度上起作用。以下是各个问题:
$('#ad_' + id).click();

这会勾选框(使其被选中),但它没有绑定任何事件。
$('#ad_' + id).attr('checked','checked').click();

这将设置属性为checked,然后单击它,立即取消选中。


这是有道理的...但是我在文档早期使用了 live('click') 来设置复选框点击事件。难道它不应该运行吗? - Jason
我认为 $(result)..click() 没有任何作用的一个原因是 live 处理程序只监听冒泡到 DOM 文档的事件,但是 $(result) 包含从 DOM 中分离出来的节点。 - Anurag

2

1
我在代码中大概有100个地方使用了.attr('checked', 'checked'),并且它按预期工作... - Jason
我相信浏览器实际上只是查找属性的存在与否,而不关心其值。 - davidtbernal

1
我怀疑这里发生的情况是,Click 实际上取消了复选框的选中状态。这是因为正如你所说,Find 方法返回了复选框。
尝试删除点击调用。
这是一些示例代码。
<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    </head>

    <body>

        <script type="text/javascript">
            function clicked() {
                console.log('clicked');
            }

            $(document).ready(function() {

                var result = '<tr><td><input type="checkbox" id="chkbx" onclick="clicked()" /></td></tr>';

                $('#edit_ads_form tbody').prepend(result);

                $('#edit_ads_form tbody').find("input").click();
            });
        </script>

        <table id="edit_ads_form">
        <tbody>

        </tbody>
        </table>
    </body>
</html>

我已经添加了一些代码,展示了复选框的选中和单击事件的触发。 - Jonathan

1

我明白了,感谢所有让我找到正确解决方法的人。这是我所做的:

首先,我不再将复选框与 click() 绑定,而是更新为在 change() 上运行。在这之后,我使用以下代码替换了原来的代码:

$('#ad_' + id).click().change();

现在一切都正常了!复选框保持选中状态并调用正确的函数。

再次感谢大家!


很好的发现.. 点击处理程序在复选框值更新之前被调用,而更改处理程序在值更新后被调用,但是当以编程方式触发单击时,更改处理程序不会被调用。 - Anurag

0

执行 $(result).find('td.select-ad input').attr('checked','checked').click(); 不会先选中它 (.attr('checked','checked')) 然后再通过点击取消选中 (.click()) 吗?

如果我漏掉了什么,请原谅,但我相当确定就是这样。这就是为什么 $('#ad_' + id).click(); 起作用,而你的其他示例不起作用的原因。


我也这么想过...但为什么它不会保持勾选状态呢? - Jason
当您调用click()时,它会取消选中框。 它在选中后再取消选中。如果您改用$(result).find('td.select-ad input').click();(删除.attr('checked','checked')部分),会怎么样呢? - davidtbernal
当我这样做时,什么都没有发生。 - Jason
你的点击处理程序中有什么内容?可能有像preventDefault或return false这样的东西阻止它被选中。 - davidtbernal
没有preventDefault或return false。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接