使用 "onclick" 事件模拟元素的中键单击

Emulating middle click on element with an "onclick" event

问题

对于站点测试,我正在尝试使用基于 some other answers on here.

的 JS 模拟如下所示的元素上的中键单击(或滚轮单击)

HTML:

<a 
  id="example-link" href="https://www.google.com/" 
  target="_blank" 
  onclick="window.open('https://www.google.com/', '', 
    'width=500, height=500, resizable=1, scrollbars=1');
     return false;">
  <span>Middle Click Me</span>
</a>

JS(想在这里改变一些东西):

var middleClick = new MouseEvent( "click", { "button": 1, "which": 2 });
jQuery("#example-link")[0].dispatchEvent( middleClick );

The issue is shown in this jsfiddle.

  1. 请注意,常规点击通常会发送一个弹出窗口。 jsfiddle 正在捕获弹出窗口并在新选项卡中将其打开。
  2. jsFiddle 被用来代替 Whosebug fiddle 以避免混淆,因为堆栈溢出 fiddle 没有正确处理 window.open()。

比较 1) 手动中键点击和 2) 运行 模拟点击的代码。

问题是,当我以编程方式触发中间单击时,它会触发打开新 window 的 onclick 方法,以及在新选项卡中打开 link(同时创建一个弹出窗口和一个选项卡,而不仅仅是一个选项卡)。如果这个link手动点击中键,弹窗不会触发。

问题

有没有更好的模拟中键点击的方法(最好是跨浏览器兼容)?这样写,我真的无法准确模拟MouseEvent脚本手动中键点击。

编辑:不幸的是,我无法更改 HTML 对象或修改 DOM 以测试完整性,因此我希望 onclick 标记保留在元素上。

据我所知,只要内联点击处理程序存在,它就会在该元素上的每个点击事件上触发,但这里有两个我想出的解决方法。

  1. 如果你真的一时半会儿都不能修改DOM,那么第一个选项就不会投放。它通过更改 DOM 然后恢复它来作弊,希望在任何人注意到之前。

  2. 第二个选项通过读取其属性并使用它们打开新选项卡而不触发新的点击事件,从而完全避免了单击 link 的需要。 (这取决于脚本对 link 元素的标记有基本的了解。具体来说,我在这里编写的代码只是假设“link”元素在其href 属性——但如有必要,您可以做出其他更复杂的假设,并根据“link”元素在运行时所具有的属性有条件地采取行动。)

注意:第三种选择是创建一个自定义事件,它具有与内置 click 事件相同的所有核心行为,但实际上不是点击事件,其想法是愚弄 onclick 处理程序通过事件进入睡眠。我不确定要完成足够好的重建这个特定轮子的工作需要多少工作。也许不会太糟糕?


在此脚本中,打开新选项卡的函数是由单击按钮触发的,但这当然只是为了演示目的,您可能会在页面加载时触发它们或作为对其他操作的回调。出于 space 节省的原因,代码段中的锚元素也略有更改

.

(因为在 Stack Overflow 片段中直接调用 window.open 似乎无法正常工作,我按照您的指示粘贴了代码 into a fiddle 以便可以看到 运行 所有名义上的荣耀。)

const
  // Identifies some DOM elements
  cheatButton = document.getElementById("cheat-button"),
  mimicButton = document.getElementById("mimic-button"),
  exampleLink = document.getElementById("example-link"),

  // Defines an event to be dispatched programmatically
  middleClick = new MouseEvent("click", {button: 1, which: 2});

// Demonstrates calling the functions
cheatButton.addEventListener("click", emulateMiddleClick); // Option 1
mimicButton.addEventListener("click", followLink); // Option 2

// Defines the functions
function emulateMiddleClick(){
  const onclickHandler = exampleLink.onclick; // Remembers onclick handler
  exampleLink.onclick = ""; // Supresses onclick handler
  exampleLink.dispatchEvent(middleClick); // Dispatches middle click
  exampleLink.onclick = onclickHandler; // Restores onclick handler
}

function followLink(){
  if(!exampleLink.href){ return; } // In case href attribute is not set
  const {href, target} = exampleLink; // Gets props by using "destructuring"

  // This doesn't seem to work in the Stack Overflow snippet...
  window.open(href, (target || "_blank")); // In case target attribute is not set

  // ...But we can at least log our intention to open a new tab
  console.log(`opening: "${href}" (in "${target}")`);
}
div{ margin: 1em; }
button{ padding: 0.3em; border-radius: 0.5em; }
span{ margin: 1.3em; }
<div>
  <button id="cheat-button">Fake Click, and Suppress Handler</button>
</div>
<div>
  <button id="mimic-button">Follow Link without Clicking</button>
</div>
  <a id="example-link"
     href="https://www.google.com/"
     target="_blank"
     onclick="window.open('https://www.google.com/', '', 'width=50, height=50');">
    <span>Middle Click Me</span>
  </a>