【问题标题】:How can I simulate a click to an anchor tag?如何模拟对锚标记的点击?
【发布时间】:2010-11-28 03:21:26
【问题描述】:

我想模拟对锚标记的点击,其中包含正确的目标处理等所有附加功能。

锚点的 DOM 对象似乎有一个“[click()][3]”方法,但并非所有浏览器都支持。 Firefox 抛出此错误:

错误:anchorObj.click 不是函数

它在 Opera 10 和 Konqueror 上也很奇怪,当它在周围 div 的 onclick 处理程序中调用时会导致无限次点击。我猜只有 IE8 可以正常工作。无论如何,我不想要它,因为主要浏览器大多都有它的问题。

我在 Mozilla 论坛中找到了 Firefox 的替代解决方案:

var evt = document.createEvent("MouseEvents"); 
evt.initMouseEvent("click", true, true, window, 
    0, 0, 0, 0, 0, false, false, false, false, 0, null); 
anchorObj.dispatchEvent(evt); 

这对我来说似乎太丑陋和麻烦了。我不知道它的兼容性如何,我想尽可能避免编写浏览器特定的代码。

我不能使用 location.href = anchorObj.href;因为它不处理“目标”属性。我可以根据目标的值进行一些硬编码,但我也想避免这种情况。

有人建议切换到 JQuery,但我不确定它处理目标属性的效果如何,因为我以前没有使用过它。

【问题讨论】:

标签: javascript html dom


【解决方案1】:

上述解决方案均未解决原始请求的一般意图。如果我们不知道锚的 id 怎么办?如果没有id怎么办?如果它甚至没有 href 参数(例如轮播中的上一个/下一个图标)怎么办?如果我们想以不可知的方式将动作应用于具有不同模型的多个锚点怎么办?这是一个示例,它执行某些操作而不是单击,然后模拟单击(对于任何锚点或其他标记):

var clicker = null;
$('a').click(function(e){ 
    clicker=$(this); // capture the clicked dom object
    /* ... do something ... */
    e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.

【讨论】:

    【解决方案2】:

    有一种更简单的方法可以实现,

    HTML

    <a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>
    

    JavaScript

    // Simulating click after 3 seconds
    setTimeout(function(){
      document.getElementById('fooLinkID').click();
    }, 3 * 1000);
    

    使用纯 javascript 模拟点击以及寻址目标属性。

    您可以在jsFiddle 上查看工作示例。

    【讨论】:

    • 这对我不起作用。期待在超时时看到一个新的浏览器窗口,但什么也得不到。
    • @TSmith,仅使用 HTML 无法做到这一点,请在此处阅读更多内容 (stackoverflow.com/questions/12939928/…)
    【解决方案3】:

    这是一个完整的测试用例,它模拟click 事件,调用所有附加的处理程序(无论它们已附加),维护"target" 属性(IE 中的"srcElement"),像正常事件一样冒泡,并模拟 IE 的递归预防。在 FF 2、Chrome 2.0、Opera 9.10,当然还有 IE (6) 中测试:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <script>
    function fakeClick(event, anchorObj) {
      if (anchorObj.click) {
        anchorObj.click()
      } else if(document.createEvent) {
        if(event.target !== anchorObj) {
          var evt = document.createEvent("MouseEvents"); 
          evt.initMouseEvent("click", true, true, window, 
              0, 0, 0, 0, 0, false, false, false, false, 0, null); 
          var allowDefault = anchorObj.dispatchEvent(evt);
          // you can check allowDefault for false to see if
          // any handler called evt.preventDefault().
          // Firefox will *not* redirect to anchorObj.href
          // for you. However every other browser will.
        }
      }
    }
    </script>
    </head>
    <body>
    
    <div onclick="alert('Container clicked')">
      <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
    </div>
    
    <button type="button" onclick="fakeClick(event, document.getElementById('link'))">
      Fake Click on Normal Link
    </button>
    
    <br /><br />
    
    <div onclick="alert('Container clicked')">
        <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
    </div>
    
    <button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>
    
    </body>
    </html>
    

    Demo here.

    它通过检查事件的target 属性(remains unchanged during propagation)检查启动模拟点击的事件对象来避免在非 IE 浏览器中的递归。

    显然 IE 在内部执行此操作时持有对其global event object 的引用。 DOM 级别 2 没有定义这样的全局变量,因此模拟器必须传入 event 的本地副本。

    【解决方案4】:

    引自https://developer.mozilla.org/en/DOM/element.click

    click 方法旨在与按钮、复选框、单选、重置或提交类型的 INPUT 元素一起使用。 Gecko 不会对可能会响应鼠标点击的其他元素(例如链接(A 元素))实现 click 方法,也不一定会触发其他元素的点击事件。

    非 Gecko DOM 的行为可能不同。

    不幸的是,您似乎已经找到了解决问题的最佳方法。

    顺便说一句,我同意您的解决方案似乎不太理想,但如果您将功能封装在一个方法中(就像 JQuery 所做的那样),它还不错。

    【讨论】:

      【解决方案5】:

      嗯,你可以像这样通过 jQuery 快速测试点击调度

      $('#link-id').click();
      

      如果您在点击尊重目标时仍然遇到问题,您可以随时这样做

      $('#link-id').click( function( event, anchor )
      {
        window.open( anchor.href, anchor.target, '' );
        event.preventDefault();
        return false;
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-06
        • 1970-01-01
        • 2022-06-10
        相关资源
        最近更新 更多