在 chrome 扩展中使用页面的 Angular JS

Posted

技术标签:

【中文标题】在 chrome 扩展中使用页面的 Angular JS【英文标题】:Using page's angular JS in chrome extension 【发布时间】:2014-04-03 16:26:31 【问题描述】:

我有一个 html 页面,其中有一些用 Angular 配置的 DOM。现在我正在构建一个 chrome 扩展来修改文本框中的值。 element.value= newValue 将不起作用,因为文本框是用 Angular 设计的。在阅读了一些资源后,我知道我需要对元素的范围进行更改。我尝试在扩展程序中这样做。

var eleScope = window.angular.element(document.querySelector('.textbox')).scope();
eleScope.$apply(function() 
  eleScope.item.request.box = newValue;
);

这似乎没有按预期工作。当我更深入地研究这个问题时,我才知道窗口范围内的角度没有得到正确的范围。

我还尝试从我的扩展程序中注入 angular.js 并直接使用 angular.element,但这似乎也无法解决问题。

我是不是错过了什么。感谢您的回复。

【问题讨论】:

【参考方案1】:

嗯.. 实际上,您应该能够使用 vanilla javascript 或 JQuery 更改值,并且不需要更新范围,因为它是双向绑定,即。更新视图会更新模型,反之亦然。

模型不更新的唯一原因是观察者更新模型仅在特定事件(如“点击”或“输入”)时触发。

所以这里的解决方案是手动触发这些事件。 这可以通过:

// the selector used is based on your example.
var elementTOUpdate = $('.textbox');
input.val('new-value');
input.trigger('input');

最后一条语句将触发元素上的“输入”事件的所有处理程序(这将触发角度观察器)并更新范围。 有关触发功能的更多信息: http://api.jquery.com/trigger/

【讨论】:

【参考方案2】:

虽然您的网页和 Chrome 扩展程序的内容脚本共享同一个 DOM,但它们具有独立的 JS 执行上下文。换句话说,尽管在您的 Chrome 扩展程序中通过 angular.element().scope() 抓取了元素,但您仍然没有访问正确的范围对象。 (有关更多信息,请参阅Chrome dev docs。)

为了将修改后的数据从您的 Chrome 扩展程序获取到页面上,您可以通过内容脚本操作 DOM,或者采取一些额外的步骤将修改后的数据获取到网页的执行上下文中(随后,进入你的控制器的范围)。

对于后者,解决方案是使用 Chrome 的 Message Passing API;具体来说,设计用于在网页和 Chrome 扩展程序之间进行通信的 API(请参阅here)。

这是文档中的一个示例:

首先,在 manifest.json 文件中为相应网站启用 API:

"externally_connectable": 
  "matches": ["http://*.foo.com/*"]

从网页发出连接到 Chrome 扩展程序的请求。在您的回调中,您将更新您的模型:

// Chrome extension's ID
var extensionId = "abcdefghijklmnoabcdefhijklmnoabc";

chrome.runtime.sendMessage(extensionId, foo: 'bar',
  function(response) 
    if (response.success) 
      $scope.myData.foo = response.data;
      $scope.$apply();
    
  );

在您的 Chrome 扩展程序的 background.js 文件中,为请求添加一个侦听器:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) 
    if (request.foo) 
      sendResponse( data: 'modified data goes here' );
    
  );

此过程将允许您的 Chrome 扩展程序将数据发送到正确的执行环境中,从而允许您的 AngularJS 应用程序使用它。

【讨论】:

【参考方案3】:

主要问题在 Jonathan Guerrera 的answer 中得到了很好的解释:您不能只在扩展中加载 Angular 并期望它能够工作,因为它是 Angular 的不同实例;真正的在另一个 JS 上下文中。


另一个可能的(虽然很老套)解决方案是inject code into the page's context。这样,您实际上是在操纵页面自己的 Angular。

它可以与between the page-level script and the content script的其他通信方式结合使用。

【讨论】:

以上是关于在 chrome 扩展中使用页面的 Angular JS的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 4 中从 chrome.runtime.sendMessage 获取回调?

如何使用 chrome.tabs.getCurrent 在 Chrome 扩展程序中获取页面对象?

使用 TypeScript 在 Chrome 扩展背景页面中调度 Redux 操作

Angular 10 PWA 中 Chrome 更新后的新警告“无法安装站点:页面无法脱机工作。从 Chrome 93 开始...”

如何与电子中的chrome扩展背景页面通信?

用于刷新页面的 Chrome 扩展