如果我还没有使用 bind 或 click 将事件处理程序绑定到它,我可以调用 jQuery 的 click() 来跟踪 <a> 链接吗?

Posted

技术标签:

【中文标题】如果我还没有使用 bind 或 click 将事件处理程序绑定到它,我可以调用 jQuery 的 click() 来跟踪 <a> 链接吗?【英文标题】:Can I call jQuery's click() to follow an <a> link if I haven't bound an event handler to it with bind or click already? 【发布时间】:2010-12-14 06:07:22 【问题描述】:

我的 javascript 中有一个计时器,它需要模拟单击链接以在时间过去后转到另一个页面。为此,我使用了 jQuery 的 click() 函数。我也使用过$().trigger()window.location,我可以让它按预期工作。

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

我在这个问题中描述的所有内容都使用 Firefox,但我也对其他浏览器将对此做什么感兴趣。

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

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

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

这会加载新页面,就像我自己单击了 a。

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


正如霍夫曼在尝试复制我的结果时所确定的那样,我上面描述的结果实际上并没有发生。我不确定是什么导致了我昨天观察到的事件,但我今天确定这不是我在问题中描述的。

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

【问题讨论】:

可能是一个解决方案:***.com/questions/31687759/… 【参考方案1】:

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

【讨论】:

【参考方案2】:

如果您查看$.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 Internet Explorer from throwing an error for some hidden elements
     
     catch (e)
     
     
 

在它调用处理程序(如果有的话)之后,jQuery 会在对象上触发一个事件。但是,如果元素不是链接,它只会为单击事件调用本机处理程序。我想这是出于某种原因故意这样做的。尽管是否定义了事件处理程序,这应该是正确的,所以我不确定为什么在您的情况下附加事件处理程序会导致调用本机 onClick 处理程序。你必须按照我的做法,逐步执行,看看它在哪里被调用。

【讨论】:

我当然可以使用我在问题中提到的 window.location 和 href 。我试图了解 jquery click() 中发生了什么,以及导致我观察到的结果的原因。 我编辑了我的答案,以显示它在 jQuery 源代码中处理链接上的 $.click() 调用的位置。 window.location 有效,但不能发布 HTTP Referrer,并且会破坏后退按钮。【参考方案3】:

锚标记上的点击处理程序是 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】:

有趣的是,这可能是 jQuery 的“功能请求”(即错误)。如果您将 jQuery 事件绑定到元素,则 jQuery click 事件只会触发元素上的单击操作(在 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 不适用于“a”标签,因为浏览器不支持使用 javascript 进行“假点击”。我的意思是,你不能用javascript“点击”一个元素。使用“a”标签,您可以触发其 onClick 事件,但链接不会改变颜色(到访问的链接颜色,在大多数浏览器中默认为紫色)。因此,让 $().click 事件与 'a' 标签一起工作是没有意义的,因为转到 href 属性的行为不是 onClick 事件的一部分,而是在浏览器中硬编码。

【讨论】:

我试了你的代码,它确实和你说的一样,但是我的代码和我上面描述的一样。我会做更多的实验,看看我是否可以将我的结果放在一个简单的例子中,你可以试试。 好的。一定是我做错了什么。当我发布我的问题时,我绝对确定它正在工作,但是自从我尝试了你的示例后,我的示例不再有效。我将返回使用 window.location 来更改页面,而不是尝试伪造点击。 确实,click() 并不是为了创建虚假点击,但有时我们可以使用它来点击带有 javascript 注入的按钮或表单,或者只是为了方便,同时在现有 javascript 之上创建一个临时热键功能。【参考方案5】:

如果您在一种情况或极少数情况下需要此功能(您的整个应用程序不需要此功能)。我宁愿让 jQuery 保持原样(出于多种原因,包括能够更新到较新的版本,CDN 等)并有以下解决方法:

// For modern browsers
$(ele).trigger("click");

// Relying on Paul Irish's conditional class names,
// <https://www.paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/>
// (via HTML5 Boilerplate, <https://html5boilerplate.com/>) where
// each Internet Explorer version gets a class of its version
$("html.ie7").length && (function()
    var eleOnClickattr = $(ele).attr("onclick")
    eval(eleOnClickattr);
)()

【讨论】:

【参考方案6】:

当然,另一种选择是只使用原生 JavaScript:

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

【讨论】:

这在 Safari 中不起作用,根据 HTML 规范,只有输入需要实现。 该死!这确实有效!但我必须说它不是“香草”javascript,因为它使用 jquery 元素,所以它是香草 jquery javascript.... 它适用于 Firefox 24 和 IE 10。 @BGM,好的,但是 click() 不在 jquery 元素上。您可以将其替换为 getElementById("..").click() 哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇+1给定:)。对于其他用户,您也可以使用: var lnk = document.getElementById("a_link"); if (lnk == null) //做一些... else lnk.click(); 在各种浏览器中测试,IE10 & Jquery 1.6.4 无法处理。【参考方案7】:

触发一个 hyperlink 元素,该元素位于要连接 jQuery .click() 到的元素内:

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

在你的脚本中,你连接到你想要点击事件的主容器。然后,您使用标准的 jQuery 方法来查找元素(类型、类和 id)并触发点击。 jQuery 输入一个递归函数来触发点击,然后你通过获取事件 'e' 和 stopPropagation() 函数来中断递归函数并返回 false,因为除了触发链接之外你不希望 jQuery 做任何其他事情。

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

另一种解决方案是将容器包装在 元素中,并将 's 作为容器而不是 's 放在里面。将 span 设置为显示块以符合 W3C 标准。

【讨论】:

【参考方案8】:

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

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

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

方法如下:

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">Wikipedia</a><br>
    <a href="https://***.com/">Stack Overflow</a>
</body>

</html>

jQuery(文件script.js

$(function()

    // Try to open all three links by pressing the button
    // - Firefox opens all three links
    // - Chrome only opens one of them without a popup warning
    // - Internet Explorer only opens one of them WITH a 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;
    );
);

对于每个链接元素,它:

    创建表单 赋予它属性 将其附加到 DOM 以便提交 提交 从 DOM 中移除表单,移除所有痕迹 *插入邪恶的笑声*

现在您有一个新的选项卡/窗口正在加载"https://google.nl"(或您想要的任何 URL,只需替换它)。不幸的是,当您尝试以这种方式打开多个窗口时,您会在尝试打开第二个窗口时收到 Popup blocked 消息栏(第一个窗口仍处于打开状态)。


有关我如何使用此方法的更多信息,请参见此处:

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

【讨论】:

【参考方案9】:

要在同一选项卡中打开超链接,请使用:

$(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;
);

【讨论】:

【参考方案10】:

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

按编号:

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

或者使用jQuery通过CSS类点击一堆链接:

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

【讨论】:

【参考方案11】:
$("#a_id")[0].click();

【讨论】:

请在分享代码的同时也尝试讲述您的代码。

以上是关于如果我还没有使用 bind 或 click 将事件处理程序绑定到它,我可以调用 jQuery 的 click() 来跟踪 <a> 链接吗?的主要内容,如果未能解决你的问题,请参考以下文章

jquery中四个事件绑定方式(bind,live,delegate,on)

jQuery的.click,.bind,.unbind,.on,.off,.delegate,.undelegate

addEventListener或attachEvent都可以用bind代替

Jquery事件绑定的4中方式对比

jQuery 事件方法

jQuery 事件方法