使用 trigger('click') 在 click 处理程序中的 jQuery

3
我正在尝试创建一个自定义确认对话框,当用户点击具有特定类的链接时。这很简单,但问题在于,如果用户在对话框中点击“确认”按钮(使用Twitter Bootstrap 3),我希望触发单击相同的链接,但这次不是显示对话框,而是跟随该链接。
一切都很好,直到我想在带有某些参数的标签上触发单击事件。这是我想要实现的非常简化的示例:
HTML:
<a class="initial" href="http://yell.com">click me</a>
<div class="dialog hidden">
    <a href="#">Click me again</a>
</div>

JavaScript:

$(document).on('click', 'a.initial', function(e, forced){
    //return true;
    if(typeof(forced) !== 'undefined' && forced === true){
        $(this).addClass('clicked');
        console.log('Clicked');
        return true;
    } else{
        e.preventDefault();
        $(this).removeClass('clicked');
        $('div').removeClass('hidden');
    }
});

$(document).on('click', 'div.dialog a', function(e){
    $(this).parent().addClass('hidden');
    $(this).parent().prev().trigger('click', [true]);
});

这里有一个JSFiddle示例

如您所见,如果单击第二个链接,则第一个链接将变为红色,并且console.log触发消息,但然后该链接不遵循url。不幸的是,我没有看到任何错误或警告可以给我一些线索。我知道我可以使用window.location = $(element).attr('href'),但我想知道为什么它不能按描述的方式工作?

非常感谢您的帮助。


我不太清楚会发生什么。当你点击“点击我”和“再次点击我”这两个链接时,会发生什么? - Alex
我猜当您点击“再次点击我”时,第一个链接的默认行为应该会触发。 - Anton
2
这可能是一个显而易见的问题,但为什么不直接将href放在第二个链接上呢? - Reinstate Monica Cellio
触发.click()事件,[true]是什么意思? - Bhojendra Rauniyar
2
上次我检查时,使用JavaScript触发点击事件无法导航链接。如果这是可能的话,垃圾站点可以在新标签页或窗口中导航到无数链接。 - CodeToad
@Archer,是的,好主意!我会使用它。 - Nik Chankov
4个回答

1

这是可能的,例如运行:

document.getElementById('nav-tags').click();

这个页面将带领用户进入标签页面。

因此,问题似乎出在jQuery触发函数上。

那么问题就变成了如何本地触发点击事件,并将强制布尔值传递到该事件中。

我想到的解决方案是删除第二个参数,并通过data在原始链接中设置一个状态:

$(document).on('click', 'a.initial', function(e){
    //return true;
    if($(this).data('trigger') === true) {
        $(this).addClass('clicked');
        console.log('Clicked');
    } else{
        e.preventDefault();
        $(this).removeClass('clicked');
        $('div').removeClass('hidden');
        $(this).data('trigger', false);
    }
});

$(document).on('click', 'div.dialog a', function(e){
    $(this).parent().addClass('hidden');
    $(this).parent().prev().data('trigger', true).get(0).click();
});

{{链接1:JSF}}


抱歉,但那不是真的。 - Alex
这个例子在Chrome 32.0.1700.107上不起作用,但如果添加setTimeout,它就能工作了。请参见这里:http://jsfiddle.net/HXeKD/。我会接受你的答案,尽管我会实现Archer的建议。 - Nik Chankov
简单的行为,复杂的解决方案。这似乎不是最好的方式。 - Frogmouth
如果你需要像setTimeout这样的hack,我建议重新考虑你的解决方案。 - Sean
解决方案是使用 triggerHandler() 而不是 trigger,就这样。 - nodws

1
您可以考虑使用这样的解决方案:

$(document).on('click', 'a.initial', function(e, forced){
    e.preventDefault();
    $('div').removeClass('hidden').find("a").attr("href",this.href);
});

:) 像 @Archer 建议的解决方案。


1

试试这个:

$(document).on('click', 'a.initial', function(e, forced){
    e.preventDefault();    
    //return true;
    if(typeof(forced) !== 'undefined' && forced === true){
        $(this).addClass('clicked');
        console.log('Clicked');
        return true;
    } else{
        //e.preventDefault();
        $(this).removeClass('clicked');
        $('div').removeClass('hidden');
    }
});

$(document).on('click', 'div.dialog a', function(e){
    e.preventDefault();
    $(this).parent().addClass('hidden');
    $(this).parent().prev().trigger('click', [true]);
});

请检查是否在正确的位置添加了 e.preventDefault()! - Bhojendra Rauniyar
啊,好的,一开始没看到。 - Anton

1

好的,我找到了一些东西。根据下面的工单,这已经是jquery中的一个错误了,但已经关闭。

http://bugs.jquery.com/ticket/11326

解决方法是在锚点内添加一个 span(或类似项),并在其中添加 click。以下是相应的演示。

http://jsfiddle.net/RCmar/2/

HTML

<a class="initial" href="http://yell.com"><span>click me</span></a>
<div class="dialog hidden"><a href="#">Click me again</a></div>

JS

$(document).on('click', 'a.initial span', function(e, forced){
    //return true;
    alert(1);
    if(typeof(forced) !== 'undefined' && forced === true){
        $(this).addClass('clicked');
        console.log('Clicked');
        return true;
    } else{
        e.preventDefault();
        $(this).removeClass('clicked');
        $('div').removeClass('hidden');
    }
});

$(document).on('click', 'div.dialog a', function(e){
    $(this).parent().addClass('hidden');
    $(this).parent().prev().children().trigger('click', [true]);
});

我以为你想要进入那个页面。你到底想要什么?我觉得我错过了重要的部分。 - A Paul
是的,我想要的确是这样,但使用你的jsfiddle示例时并没有成功(Chrome 32.0.1700.107)。我会采用Archer的建议,但也可以像被接受的答案中那样添加setTimeout()来按你的方式实现。 - Nik Chankov
1
好的。实际上我正在使用Firefox。无论如何,最重要的是它已经被修复了。 - A Paul

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