25

我试图弄清楚我一直遇到的这个奇怪的问题,根本原因是实时点击和触发之间的区别.click()

我不会深入讨论问题的细节,但基本上当你点击输入按钮时它工作正常(有一个onclick事件)。但是,如果我.click()从其他地方打电话(而不是物理单击按钮),它就不能正常工作。

我的问题是 - 有没有办法真正复制按钮的实际点击?


编辑

问题:我正在打开一个加载内联 PDF 的新窗口(aspx 页面)。如果我真的点击链接,窗口会打开并加载 PDF。如果我使用.click()该窗口打开并提示我下载 PDF 文件。我已经通过有关提示的 Adob​​e Reader 设置、浏览器设置和注册表设置 - 我知道这些可能是影响大局的因素,但现在我担心为什么鼠标单击和 .click( ) 正在做任何不同的事情。

4

4 回答 4

21

在阅读以下讨论如何规避问题的内容之前,让我更全面地回答您开始遇到问题的原因:

现代浏览器根据您单击的鼠标按钮、是否按住Shift/ Ctrl/等对链接采取不同的操作Alt。例如,在 Chrome 中,如果您中键单击链接而不是左键单击,浏览器将自动在新选项卡中打开窗口。

当您使用 时.click(),jQuery 必须对您单击的“方式”做出假设-并且您会得到默认行为-在您的情况下,这不是正确的行为。您需要以设置的形式为浏览器指定“正确”的设置MouseEvents才能解决问题。

现在,对修复它的方法进行简短讨论:

当您使用.click()不带参数的 jQuery 事件时,这实际上并不是对相关元素“假装点击”。相反,根据http://api.jquery.com/click/上的 jQuery 文档:

...当.click()不带参数调用时,它是 .trigger("click") 的快捷方式

这意味着当您触发时$('#div1').click()- 如果事件没有实际的 jQuery 处理程序'click',您将获得默认处理。因此,请考虑以下两种情况:

案例一

<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
    $('#myLink').click();
</script>

在第一个场景中,.click()调用什么也不做,因为它没有处理程序。事件触发,但没有任何东西可以捕捉和响应 - 因此使用a标签的默认处理,并且用户被带到/some/link/- 而且由于您没有指定哪个鼠标按钮或任何其他参数 - 它是真正的默认值。

案例2

<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
    $('#myLink').bind('click', function (ev) {
        ev.preventDefault();
        ev.stopPropagation();

        alert('you clicked me!');
    }).click();
</script>

在这种情况下,因为click创建了一个处理程序,所以当用户单击链接时 -ev.preventDefault()ev.stopPropagation()调用将停止发生默认处理,并且将触发警报。

但是,此时您有一个ev代表MouseEvents- 的对象,您可以根据需要更改设置。例如,您可以执行以下操作:

ev.altKey = true; // Held Alt
ev.button = 1;    // Middle Mouse Button

这些设置将更改处理事件的默认方法。

替代的非 jQuery 解决方案

您还可以通过修改以下代码来真正模拟按钮单击。

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.
    }
  }
}

(有关更完整的实现,请参阅原帖:如何模拟对锚标记的点击? - 并查看所选答案)

这实际上会使浏览器相信您通过以与浏览器的默认处理程序相同的方式从头开始构建事件来单击鼠标单击锚点/跨度/等 - 除了您可以覆盖某些设置。但是,我不建议使用这种方法,因为它更容易在跨浏览器应用程序上中断,并且您必须弄清楚所有参数映射到什么。

于 2012-06-20T20:59:12.687 回答
15

我使用这个函数来真正模仿鼠标点击:

function clickLink(link) {
    var cancelled = false;

    if (document.createEvent) {
        var event = document.createEvent("MouseEvents");
        event.initMouseEvent("click", true, true, window,
            0, 0, 0, 0, 0,
            false, false, false, false,
            0, null);
        cancelled = !link.dispatchEvent(event);
    }
    else if (link.fireEvent) {
        cancelled = !link.fireEvent("onclick");
    }
}
于 2012-06-20T20:47:48.513 回答
6
  $('img').click(function(event){
    console.log(event.hasOwnProperty('originalEvent')); // output : true

  });
  $('img').trigger("click",function(event){
    console.log(event.hasOwnProperty('originalEvent')); // output : false

 });
于 2017-04-18T06:38:31.597 回答
1

要创建和触发与 user-click 相同的点击事件:

function simulateClick() {
  var event = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true
  });
  var cb = document.getElementById('checkbox');  //whichever element you want to click
  var cancelled = !cb.dispatchEvent(event);
  if (cancelled) {
    // A handler called preventDefault.
    alert("cancelled");
  } else {
    // None of the handlers called preventDefault.
    alert("not cancelled");
  }
}

当然,像这样调用函数。

simulateClick();

来源:https ://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

注意:不推荐使用 initMouseEvent()。避免使用它,而是使用 MouseEvent() ,如本解决方案所示。

于 2019-11-25T08:53:50.417 回答