【问题标题】:Trying to simulate label click试图模拟标签点击
【发布时间】:2012-06-07 06:40:12
【问题描述】:

为什么这不起作用?标签位于 .item 父级内。我不想把它放在块元素之外,因为它是无效的。

所以我试图模拟一个标签点击:

$(".item").click(function(){
    $(this).find("label").click();
});

编辑:它应该触发标签并检查收音机。

<script type="text/javascript">
    $(document).ready(function () {
        $(".item").click(function() {
            $(this).find("label").click();
        });
    }); 
</script>


<div class="item">
    <h4>Item</h4>
    <ul>                
        <li>Description</li>
    </ul>
     <div class="radio-container">
        <div class="radio-stack">
            <input type="radio" class="styled" id="item1">
        </div>
        <label for="item1">$100</label>
    </div>
</div>

【问题讨论】:

  • 你能显示你的html代码吗?

标签: jquery jquery-events event-capturing


【解决方案1】:

由于此标签附加到某些输入(使用 for 属性),您可以尝试以下操作:

var inputID = $(this).find("label").attr("for");
$('#' + inputID).click();

但是您应该小心:由于您的输入是带有.item 类的 div 中,模拟在收音机中的点击将再次触发您的自定义处理程序,从而导致无限循环。如果可能,只需将无线电checked 属性设置为true,而不是模拟点击:

$('#' + inputID).attr("checked",true);

jsFiddle 的工作示例)

否则,您需要找到一种方法将该无线电从.item 选择器中排除,以避免出现无限循环。

更新:在使用 not 选择器进行了一番挣扎后,我想出了一个快速而肮脏的技巧:使用全局(到 ready 闭包)变量来控制是否没有发生模拟点击:

var updating = false;
$(".item").click(function() {
    if ( !updating ) {
        var inputID = $(this).find("label").attr("for");
        updating = true;
        $('#' + inputID).click();
        updating = false;
    }
});

工作示例here。 IMO Ayman Safadi 的答案更好,但如果您无法使其跨浏览器工作,则可以使用此替代方法作为起点。

【讨论】:

  • 直接检查收音机是我的第一个想法。但是由于我使用ryanfait.com/resources/custom-checkboxes-and-radio-buttons/… 来设置我的收音机样式,它似乎只在第二次点击时才检查它,这就是我尝试模拟标签点击的原因。现在我知道为什么标签的想法至少不起作用了。
  • Ayman Safadi 的答案应该会更好,但如果您仍然遇到问题(例如,如果 stopPropagation 阻止您的收音机中的其他内容正常工作)请查看我更新的答案。
  • 这解决了跨浏览器问题,所以我将这个标记为答案。谢谢。
【解决方案2】:

严格回答您的问题,它不起作用,因为它会导致“点击”的无限循环,并且您的浏览器只是默默地杀死了该事件。

运行这个演示,看看你的 JS 控制台:http://jsfiddle.net/bRyR3/

divcapturing label 点击事件。换句话说,JavaScript 会这样解释你的逻辑:

点击.item时,触发labelclick”事件。

label.item 内部,因此如果label 被点击,.item 也是如此。

点击.item时,触发labelclick”事件。

label.item 内部,因此如果label 被点击,.item 也是如此。

点击.item时,触发labelclick”事件。

label.item 内部,因此如果label 被点击,.item 也是如此。

等等……

正在研究实际解决方案。


解决方案

$('.item').on('click', function(e) {
    console.log('click');
    $('label', $(this)).trigger('click');
});

$('.item label').on('click', function(e) {
    e.stopPropagation();
});

​ 这将阻止.item 捕获labelclick 事件。

工作演示:http://jsfiddle.net/bRyR3/1/

【讨论】:

  • 所以这就是 FF 崩溃的原因......实际的解决方案可能非常简单 - 将标签放在 .item 之外。不完美,但我可以使用它。
  • @domino,我刚刚添加了一个解决方案。
【解决方案3】:

由于在寻找解决方案时会弹出此问答,因此有第三种方法可以解决此问题:

JQuery 允许通过使用 trigger() 将自定义参数发送到 on() 事件处理程序

https://api.jquery.com/trigger/

这意味着,只需告诉事件处理程序当前事件是“人为的”,就可以避免死循环:

$( document ).on( 'click touch', '.item', function( event, artificial ) {
     if( artificial ) return;
     
     $(this).find("label").trigger( 'click', [ true ] );
} );

这具有不停止传播(或依赖传播)的优点,同时也不会摸索不同的输入类型(复选框、收音机、文本等)。它只是模拟对标签的点击,无需我们进行任何额外的工作或任何无限循环。

【讨论】:

    猜你喜欢
    • 2018-03-07
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 2011-07-18
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多