【问题标题】:Triggering a click event from content script - chrome extension从内容脚本触发点击事件 - chrome 扩展
【发布时间】:2013-07-23 19:29:07
【问题描述】:

在我的 chrome 扩展程序的内容脚本中,我点击了来自某些网站的网页上的某些链接/按钮。为此,我在内容脚本中使用了以下代码(我在内容脚本中嵌入了 jQuery):

$(css_selector).trigger("click")

这适用于大多数网站。

但是,在 delta.com、match.com 和 paypal.com 等某些网站上,这种触发元素点击的方式不起作用。在 delta.com 上,当我尝试在内容脚本中触发时抛出以下异常:

Error: An attempt was made to reference a Node in a context where it does not exist.
Error: NotFoundError: DOM Exception 8

奇怪的是,如果我在 delta.com 上打开 javascript 控制台,包含一个 jQuery 并尝试相同的点击触发代码 sn-p,它就可以工作。

在 match.com 和 paypal.com 上,触发在内容脚本中根本不起作用,也没有错误。我什至无法像在 delta.com 上那样通过 javascript 控制台触发“点击”事件。

如果我手动使用鼠标点击,这三个站点上的一切都正常。因此,我也尝试使用 mousedown()、mouseup() 进行模拟,但也没有用。

这似乎是个问题,因为来自这些网站的 javascript 正在劫持和忽略事件。我试图从这些站点读取代码以查看发生了什么,但代码太多了。

有没有人知道这里发生了什么以及如何解决它?

【问题讨论】:

  • 可能重复:how to send 'keydown' event to page's input? - jQuery 的 click 触发函数不会触发非 jQuery DOM 点击监听器 (jsfiddle.net/k2W6M)。您的代码工作的站点可能已经使用 jQuery 作为其侦听器,因此您的 jQuery 触发器可以工作。或者,某些网站可能会check to see if your clicks are actual or programmatic
  • 我检查了,$('li.business a')[0].click() 似乎可以在 paypal.com 主页上使用。
  • @apsillers,谢谢。我关注了您的链接,并在最后一个链接中找到了答案。现在我创建 MouseEvents 并调度它。这适用于所有网站。

标签: javascript jquery google-chrome-extension


【解决方案1】:

由于浏览器扩展沙盒和基本 jQuery 功能,您无法使用 triggerclick 触发非 jQuery 点击事件。

但是,您可以调用原始 DOM 元素 click 方法,该方法的作用与使用鼠标单击该元素完全一样。只需使用[0] 访问 DOM 元素:

$(css_selector)[0].click();

虽然您很少需要,但您可以使用each 中的相同代码触发所有匹配按钮。由于each 中的 this 是 DOM 元素,因此非常简单:

$(css_selector).each(function(){
    this.click();
});

【讨论】:

  • 很好的建议,但您能否将解决方案概括为具有多个元素的选择器?
  • @Xan:在真实页面上触发多个同时鼠标单击是最不寻常的。你能提供一个你需要的例子吗?
  • 这个问题,例如:stackoverflow.com/q/28398550/934239(触发多个“like”按钮)
  • @Xan:现在也覆盖了多个按钮。
【解决方案2】:

jQuery 的点击触发功能不会触发非 jQuery DOM 点击监听器(jsfiddle.net/k2W6M)。

jQuery 文档确实应该指出这个事实。我敢肯定,不止一些人为此疯狂追逐。

几天来我一直在为同样的问题苦苦挣扎,试图在带有 .click() 和 .trigger("click") 的链接上触发 onclick 处理程序,但都是徒劳的,直到我看到了。

为了得到这个问题的完整答案,向元素发送MouseEvent 与单击元素的效果相同。以下代码对我有用,并且在尝试从内容脚本单击页面上的元素/链接时应该可以工作:

$(css_selector)[0].dispatchEvent(new MouseEvent("click"))

【讨论】:

  • 真正令人惊讶的 jQuery 文档并没有说明这一点。事实上,它似乎支持这一点。相当误导。
  • 这拯救了我的一天..!谢谢
  • 太好了,感谢您的解决方案。我使用了.dispatchEvent(new MouseEvent("change")),因为那是我想要调度的事件。
【解决方案3】:

content_script 被沙盒执行,见https://developer.chrome.com/extensions/content_scripts

但是,内容脚本有一些限制。他们不能:

  • 使用由其扩展页面定义的变量或函数
  • 使用网页或其他内容脚本定义的变量或函数

content_script中的$不能访问网页上的$,但是事件数据存储在$里面,所以我们无法触发。

// taken from jQuery#1.11.2 from line4571, trigger method
...

// jQuery handler
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
    handle.apply( cur, data );
}

// Native handler
handle = ontype && cur[ ontype ];

【讨论】:

  • 这段代码sn-p有什么关系?
  • @Xan 假设 cur 是 DOM 对象,jQuery._data(cur,"events") 得到 jQuery.cache[cur[jQuery.expando]].events ,这表明 events 数据存储在 jQuery.cache 对象中,并且它是沙箱执行的。所以在我们的内容脚本中,我们无法访问网页的jQuery对象,因为上面代码中的handle为空。
猜你喜欢
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
相关资源
最近更新 更多