代码之家  ›  专栏  ›  技术社区  ›  Sedat Kapanoglu johnnywhoop

如何模拟点击锚标记?

  •  45
  • Sedat Kapanoglu johnnywhoop  · 技术社区  · 15 年前

    我想用正确的目标处理等所有额外功能来模拟点击锚标记。

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

    错误:anchorobj.click不是函数

    它在Opera 10和Konquerror上也很奇怪,当它被称为周围一个分区的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;,因为它不处理“target”属性。我可以根据目标值进行一些硬编码,但我也希望避免这种情况。

    有人建议切换到jquery,但我也不确定它处理目标属性有多好,因为我以前没有处理过它。

    5 回复  |  直到 6 年前
        1
  •  62
  •   Crescent Fresh nosklo    15 年前

    下面是一个完整的测试用例,它模拟 click 事件,调用附加的所有处理程序(无论它们是如何附加的),维护 "target" 属性( "srcElement" 在IE中,气泡就像正常事件一样,并模拟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 )

    很明显,这在内部是指 global event object . dom级别2没有定义这样的全局变量,因此模拟器必须传递其本地副本 事件 .

        2
  •  11
  •   Peter Bailey    15 年前

    好吧,您可以非常快速地通过jquery测试click调度,就像这样

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

    如果你仍然对点击尊重目标有问题,你可以一直这样做。

    $('#link-id').click( function( event, anchor )
    {
      window.open( anchor.href, anchor.target, '' );
      event.preventDefault();
      return false;
    });
    
        3
  •  11
  •   Chris Shouts    15 年前

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

    click方法用于button、checkbox、radio、reset或submit类型的输入元素。Gecko不会在其他元素上实现click方法,这些元素可能会响应鼠标单击,例如链接(a元素),也不一定会触发其他元素的click事件。

    非壁虎DOMS的行为可能不同。

    不幸的是,听起来你已经找到了解决问题的最佳方法。

    顺便说一句,我同意您的解决方案似乎不太理想,但是如果您将功能封装在一个方法中(就像jquery会做的那样),那就没有那么糟糕了。

        4
  •  6
  •   Gaurav Gandhi    7 年前

    有一个更简单的方法来实现它,

    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 .

        5
  •  0
  •   Peter Kionga-Kamau    6 年前

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

    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.