【问题标题】:Trigger click event for react element触发反应元素的点击事件
【发布时间】:2023-01-05 02:56:31
【问题描述】:

我正在尝试使用开发人员控制台为反应元素模拟点击。为了方便大家测试而不是使用我的代码,请使用以下反应网站https://www.tradingview.com/chart/?symbol=COINBASE%3ABTCUSD

这发生在 Facebook 等其他网站以及某些项目上。这只是一个简单的无登录站点来测试。

我尝试单击的部分是监视列表中的一个项目。在下图中,我用箭头指向它。当您单击屏幕右上角“开始免费试用”蓝色按钮下方闹钟图标上方的按钮时,会出现特定菜单。

要了解我预期会发生什么,请尝试单击该行中的任何列,例如 SPX、NDQ、DJI 等……(您应该会看到页面和股票图表发生变化)

我目前可以“排序”模拟点击,但它所做的只是突出显示该行,而不是像执行实际点击时那样实际更改页面。

要明白我的意思,请按 F12 打开开发人员控制台并键入如下命令。

document.getElementsByClassName("wrap-XdW9S1Ib")[2].dispatchEvent(new Event('click',{bubbles:true}));

类名称对您来说可能不同,因此您可能需要在开发人员控制台的元素菜单中四处寻找以找出适合您的名称。搜索 wrap- 一词,您最终应该会找到正确的类集。

在我上传的图片中,您会注意到点击事件触发了 NDQ 周围的蓝色背景(因为这是包装类的“第三”元素)。请注意,它并没有改变实际的页面和股票图表。

我曾尝试发送其他事件,如“输入”、“选择”、“提交”、“dblclick”,但均无济于事。我也试过点击那个包装器的子元素,每一个都没有运气。

我的目标是让它模拟点击并实际让它因点击而改变页面。

我目前的方法做错了什么?

【问题讨论】:

  • 有点滑稽:你做错的是期望有人为你分析一个外部(可能是专有的)网站。
  • @Tibrogargan 我仅将此网站用作示例,因为其他 React 网站也会发生这种情况,如果您愿意,我可以使用其他网站作为示例吗?这只是最容易测试的一个。我不明白为什么它在这里不起作用。
  • 那将是更可取的。这与 minimal reproducible example 相去甚远
  • 你试过'hover'吗?
  • 谢谢,我还没有,我会尽快尝试

标签: javascript reactjs onclick dom-events onclicklistener


【解决方案1】:

好的,所以我想通了。事实证明,React 对 isTrusted: true 的事件非常挑剔,它还需要一个属性 nativeEvent : {detail:1}

所以这会很复杂,但要正确模拟点击,您必须首先确定“onClick”反应元素的位置。

在我的例子中,元素是来自我的 tradingview 示例的 <div class="wrap-XdW9S1Ib" draggable="true">

多亏了方便的命令monitorEvents($0,"click"),您可以在控制台中输入它,它将记录元素选项卡视图中最后选定项目的所有点击。

使用它,您可以键入如下内容:var elem = $0; 以轻松设置元素,或者您可以像我在问题中所做的那样选择它。

接下来,要了解的关键是事件的 isTrusted 属性用于确定点击是否是真正的点击。这就是 elem.click() 不起作用的原因!

那么我们如何解决这个问题呢?

通过在顶部手动放置一个点击事件并将该事件记录到一个名为 event! 的全局变量中。

var event;
elem.addEventListener("click",function(e){console.log("click detected");event=e});

这里的关键是event=e 把它存到全局变量中.现在单独执行此操作是不够的,就好像您调用 elem.click() 一样,这只会简单地调用两个单击事件,但仍然无法正常工作。

但是,REACT 使用合成事件并使用“事件”对象来传递其数据。

因此,如果您知道取代通常的 onclick 的真正 onClick 事件在哪里,您可以直接使用此 isTrusted: true 事件调用它。

键入这样的命令以查找对象的 __reactProps。

for(key in elem){console.log(key)}

这将打印出所有对象。在我的例子中,onClick 隐藏在elem.__reactProps$3jcigo40r49

现在只需调用:

elem.__reactProps$3jcigo40r49.onClick(event);

并且它会正确地将其视为实际的鼠标单击并触发您期望的所有更改。除了......等等,它仍然没有工作,因为你收到一条错误消息,说无法读取未定义的属性(读取“详细信息”)。

要解决此问题,只需在控制台中说即可。

event.nativeEvent = {detail:1}

现在再次尝试之前的命令,它将起作用!


编辑 - 下面的答案更容易

事实证明,还有一个更简单的解决方案。

看来在我的情况下 isTrusted 并不重要。是 nativeEvent: {details:1} 做到了。

只需像这样创建一个新的指针事件。

var testEvent = new PointerEvent("click");
testEvent.nativeEvent = {detail:1}
elem.__reactProps$3jcigo40r49.onClick(testEvent);

3行代码,点击即可!

【讨论】:

  • 很好的分析。这似乎对很多事情都有用
  • 实际上,当您尝试制作测试套件以自动测试您的代码以确保它适用于公众时,它很有用。
【解决方案2】:

当我尝试这个时,我得到一个错误:

未捕获的类型错误:document.querySelector(...).__reactProps$6jhf67fyckh.onClick 不是函数

我在 Chrome 开发控制台中执行此操作。 document.querySelector(path) 正在自动完成显示的 __reactProps:

document.querySelector("#root > div > div > div.sc-hQRsPl.bqPigl > div > div.sc-papXJ.iIImKA > form > div:nth-child(9) > input").__reactProps$6jhf67fyckh
{value: 'Redeem', disabled: false, type: 'submit', className: 'sc-jZiqTT izoCLX'}
className: "sc-jZiqTT izoCLX"
disabled: false
type: "submit"
value: "Redeem"
[[Prototype]]: Object

此外,由于 __reactPops$6jhf67fyckh 似乎每次都会生成,是否可以通过其他方式获取它?

【讨论】:

    猜你喜欢
    • 2018-08-02
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2017-02-26
    • 2017-12-05
    • 2011-05-06
    相关资源
    最近更新 更多