尝试模拟标签单击



为什么这不起作用?标签位于.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>

由于此标签附加到某些输入(使用 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;
    }
});

这里的工作示例。IMO Ayman Safadi的答案更好,但是如果您在使其跨浏览器工作时遇到困难,则可以将此替代方案用作起点。

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

运行此演示,并查看您的 JS 控制台:http://jsfiddle.net/bRyR3/

div正在捕获label单击事件。换句话说,JavaScript 是这样解释你的逻辑的:

当您单击.item时,触发label"click"事件。

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

当您单击.item时,触发label"click"事件。

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

当您单击.item时,触发label"click"事件。

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捕捉label click事件。

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

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

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 ] );
} );

这样做的好处是不停止传播(或依赖它),同时也不会摸索不同的输入类型(复选框、无线电、文本等)。它只是模拟对标签的点击,而无需我们进行任何额外的工作或任何无休止的循环。

最新更新