我可以调用jquery click()来关注<a> link if I haven&#39;t bound an event handler to it with bind or click already?</a>

时间:2009-11-07 22:02:41

标签: javascript jquery firefox events click

我的JavaScript中有一个计时器,需要模拟点击一个链接,一旦时间流逝就转到另一个页面。要做到这一点,我正在使用jQuery的click()函数。我也使用了$().trigger()window.location,我可以按照预期使用这三个。

我观察到click()的一些奇怪的行为,我试图了解发生了什么以及为什么。

我正在使用Firefox来解决这个问题,但我也对其他浏览器会对此做些什么感兴趣。

如果我没有使用$('a').bind('click',fn)$('a').click(fn)来设置事件处理程序,那么调用$('a').click()似乎什么都不做。它不会为此事件调用浏览器的默认处理程序,因为浏览器不会加载新页面。

但是,如果我先设置一个事件处理程序,那么它就会按预期工作,即使事件处理程序什么都不做。

$('a').click(function(){return true;}).click();

这会加载新页面,就像我自己点击了一样。

所以我的问题是双重的:这是一种奇怪的行为,因为我在某处做错了什么?如果我没有创建自己的处理程序,为什么调用click()对默认行为不采取任何行动?

修改

当霍夫曼确定他试图复制我的结果时,我上面描述的结果实际上并没有发生。我不确定是什么原因引起了我昨天观察到的事件,但我今天肯定这不是我在问题中所描述的。

所以答案是你不能在浏览器中“伪造”点击,并且所有jQuery都会调用你的事件处理程序。您仍然可以使用window.location更改页面,这对我来说很好。

11 个答案:

答案 0 :(得分:239)

另一个选择当然是使用vanilla javascript:

document.getElementById("a_link").click()

答案 1 :(得分:88)

有趣的是,这可能是jQuery的“功能请求”(即bug)。如果将jQuery事件绑定到元素,则jQuery单击事件仅触发元素上的单击操作(在DOM上调用onClick事件)。你应该去jQuery邮件列表(http://forum.jquery.com/)并报告这个。这可能是想要的行为,但我不这么认为。

编辑:

我做了一些测试,你说的是错误的,即使你将一个函数绑定到'a'标签,它仍然没有带你到href属性指定的网站。请尝试以下代码:

<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script>
  $(document).ready(function() {
   /* Try to dis-comment this:
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }
 </script>

</head>
<body>
 <input type="button" onclick="button_onClick()">
 <br>
 <a id='a' href='http://www.google.com' onClick="a_onClick()"> aaa </a>

</body>
</html> 

除非您直接点击链接(带或不带注释代码),否则它永远不会进入google.com。另请注意,即使将click事件绑定到链接,单击按钮后它仍然不会变为紫色。如果直接点击链接,它只会变紫。

我做了一些研究,似乎.click不会与'a'标签一起使用,因为浏览器不会使用javascript支持“假点击”。我的意思是,你不能用javascript“点击”一个元素。使用'a'标签,您可以触发其onClick事件,但链接不会更改颜色(对于访问过的链接颜色,在大多数浏览器中默认为紫色)。因此,将$()。click事件与'a'标记一起使用是没有意义的,因为转到href属性的行为不是onClick事件的一部分,而是在浏览器中硬编码。

答案 2 :(得分:62)

如果你看一下$.click函数的代码,我敢打赌有一个条件语句,它检查元素是否有在click事件进行之前注册的侦听器。为什么不从链接中获取href属性并手动更改页面位置?

 window.location.href = $('a').attr('href');

编辑:这就是为什么它没有点击trigger函数,版本1.3.2的jQuery源:

 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
        event.result = false;

    // Trigger the native events (except for clicks on links)
    if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
        this.triggered = true;
        try {
            elem[ type ]();
        // prevent IE from throwing an error for some hidden elements
        } catch (e) {}
    }

在调用处理程序(如果有的话)之后,jQuery会在对象上触发一个事件。但是,如果元素不是链接,它仅调用单击事件的本机处理程序。我想这是出于某种原因有目的地完成的。虽然是否定义了事件处理程序,但这应该是正确的,因此我不确定为什么在您的情况下附加事件处理程序会导致调用本机onClick处理程序。你必须做我做的事情并逐步执行以查看它的调用位置。

答案 3 :(得分:5)

在锚标签上点击处理程序是jQuery中的一个特例。

我认为你可能会对主播的onclick事件(浏览器已知)和jQuery对象的click事件感到困惑,该事件包含了DOM的锚标记概念。

您可以下载jQuery 1.3.2源代码here

源的相关部分是第2643-2645行(我已将其拆分为多行,以便更容易理解):

// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;

答案 4 :(得分:3)

触发要连接jquery的元素内部的超链接元素.click()

<div class="TopicControl">
    <div class="articleImage">
       <a href=""><img src="" alt=""></a>
    </div>
</div>

在您的脚本中,您可以连接到想要单击事件的主容器。然后使用标准的jquery方法来查找元素(类型,类,id)并触发单击。会发生什么是jquery进入一个递归函数来触发click并通过接受事件'e'和stopPropagation()函数来中断递归函数并返回false,因为你不希望jquery做任何其他事情而是激活链接。 / p>

$('.TopicControl').click(function (event) {
         $(this).find('a').click();
        event.stopPropagation();
        return false;
     });

替代解决方案是将容器包装在元素中,并将其作为容器放在内部而不是放在容器中。将跨度设置为显示块以符合w3c标准。

答案 5 :(得分:3)

JS / jQuery不支持以编程方式“点击”链接的默认行为。

您可以做的是创建表单并提交。这样您就不必使用window.locationwindow.open,它们通常被浏览器阻止为不需要的弹出窗口。

此脚本有两种不同的方法:一种尝试打开3个新标签/窗口(在IE和Chrome中只打开1个,下面有更多信息),另一种在链接点击时触发自定义事件。

以下是:

HTML

<html>
<head>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
    <button id="testbtn">Test</button><br><br>

    <a href="https://google.nl">GOOGLE</a><br>
    <a href="http://en.wikipedia.org/wiki/Main_Page">WIKI</a><br>
    <a href="https://stackoverflow.com/">SO</a>
</body>
</html>

jQuery(script.js)

$(function()
{ 
    // Try to open all 3 links by pressing the button
    // - Firefox opens all 3 links
    // - Chrome only opens 1 of them without popup warning
    // - IE only opens 1 of them WITH popup warning
    $("#testbtn").on("click", function()
    {
        $("a").each(function()
        {
            var form = $("<form></form>");
            form.attr(
            {
                id     : "formform",
                action : $(this).attr("href"),
                method : "GET",
                // Open in new window/tab
                target : "_blank"
            });

            $("body").append(form);
            $("#formform").submit();
            $("#formform").remove();
        });
    });

    // Or click the link and fire a custom event 
    // (open your own window without following the link itself)
    $("a").on("click", function()
    {
        var form = $("<form></form>");
        form.attr(
        {
            id     : "formform",
            // The location given in the link itself
            action : $(this).attr("href"), 
            method : "GET",
            // Open in new window/tab
            target : "_blank"              
        });

        $("body").append(form);
        $("#formform").submit();
        $("#formform").remove();

        // Prevent the link from opening normally
        return false;
    });

});

它为每个链接元素做了什么:

  1. 创建表单
  2. 赋予其属性
  3. 将其附加到DOM,以便提交
  4. 提交
  5. 从DOM中删除表单,删除所有痕迹*插入邪恶的笑*
  6. 现在您有一个新的标签/窗口加载"https://google.nl"(或任何您想要的网址,只需替换它)。不幸的是,当您尝试以这种方式打开多个窗口时,在尝试打开第二个窗口时会收到Popup blocked消息栏(第一个仍然打开)。


    有关如何使用此方法的更多信息,请访问:

    Opening new window/tab without using window.open or window.location.href

答案 6 :(得分:2)

它什么也没做,因为没有事件绑定到事件。如果我没记错的话,jQuery维护自己的事件处理程序列表,这些事件处理程序绑定到NodeLists以实现性能和其他目的。

答案 7 :(得分:2)

如果您需要此功能一个案例或很少casses。 (您的整个应用程序不需要此功能)我宁愿保留jQuery(出于多种原因,包括能够更新到更新版本,CDN等)并具有以下解决方法:

// For modren Browsers
$(ele).trigger("click");

// Relaying on Paul Irish's conditional class names http://bit.ly/HWIpAp (via HTML5 Boilerplate http://bit.ly/HUzi3I) where each IE version gets a class of its Version
$("html.ie7").length && (function(){
    var eleOnClickattr = $(ele).attr("onclick") 
    eval(eleOnClickattr);
  })()

答案 8 :(得分:1)

要在同一标签中打开超链接,请使用:

$(document).on('click', "a.classname", function() {
    var form = $("<form></form>");
    form.attr(
    {
        id     : "formid",
        action : $(this).attr("href"),
        method : "GET",
    });

    $("body").append(form);
    $("#formid").submit();
    $("#formid").remove();
    return false;
});

答案 9 :(得分:1)

您可以使用jQuery为该元素选择jQuery对象。然后,获取底层DOM元素并调用其click()方法。

由id

$("#my-link").each(function (index) { $(this).get(0).click() });

或使用jQuery按CSS类点击一堆链接

$(".my-link-class").each(function (index) { $(this).get(0).click() });

答案 10 :(得分:-2)

$("#a_id")[0].click();