.click() 和实际单击按钮之间的区别? (javascript/jQuery)

Posted

技术标签:

【中文标题】.click() 和实际单击按钮之间的区别? (javascript/jQuery)【英文标题】:Difference between .click() and actually clicking a button? (javascript/jQuery) 【发布时间】:2012-06-23 01:58:59 【问题描述】:

我正试图找出我一直遇到的这个奇怪问题,根本原因是实时点击和触发.click()之间的差异@

我不会深入讨论问题的细节,但基本上当您单击输入按钮时它工作正常(有一个onclick 事件)。但是,如果我从其他地方(而不是物理单击按钮)调用 .click(),它将无法正常工作。

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


编辑

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

【问题讨论】:

我不会详细讨论问题的细节”......但这就是我们在这里所做的。听起来其他东西不起作用,因为.click() 应该触发点击。 可能是按钮在单击时正在提交表单(我不记得这是否适用于click),或者它可能处理mouseup 和/或mousedown事件而不是click @Shannon:如果我的回答对您有帮助,请接受它作为正确答案,以便将此问题标记为已解决。如果您仍然有问题,我很乐意提供帮助。谢谢! 【参考方案1】:

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

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

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

现在,开始简短讨论修复它的方法:

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

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

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

案例 1

<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() 调用将停止发生默认处理,并触发警报。

然而,此时,您有一个代表MouseEventsev 对象——您可以根据需要更改设置。例如,您可以执行以下操作:

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.
    
  

(有关更完整的实现,请参阅原帖:How can I simulate a click to an anchor tag? - 并查看所选答案)

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

【讨论】:

【参考方案2】:

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

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");
    

【讨论】:

【参考方案3】:
  $('img').click(function(event)
    console.log(event.hasOwnProperty('originalEvent')); // output : true

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

 );

【讨论】:

请添加一些描述来解释您的代码将修复什么以及如何修复它。 @Dvir Azulay 代码完美地模拟了鼠标点击,我只是举例来检查点击是我的鼠标点击还是触发器。 也许不是 OP 想要的,但这有助于我区分实际点击和触发点击事件,这正是我想要的。谢谢! 谢谢,这帮助我捕获了用户点击,而不是脚本点击。【参考方案4】:

创建和触发与用户点击相同的点击事件:

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() ,如本解决方案所示。

【讨论】:

以上是关于.click() 和实际单击按钮之间的区别? (javascript/jQuery)的主要内容,如果未能解决你的问题,请参考以下文章

F5,Ctrl + F5和单击刷新按钮之间的区别?

click和onclick本质的区别

点击事件click和.on('click') 两者之间的区别

j-query按钮单击时选择列表文本不改变[重复]

当 .click() 不起作用时,如何以编程方式单击此页面上的按钮?

clickat和clickon的区别