如何将Angularjs与Gassmonkey一起使用来修改网页? [英] How to use angularjs with greasemonkey to modify web pages?

查看:100
本文介绍了如何将Angularjs与Gassmonkey一起使用来修改网页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用angularjs和油脂猴子修改网页的行为.我想知道,最好的方法是什么?在编写一些角度代码之前,我应该使用jquery向DOM元素注入诸如"ng- * "之类的属性吗?还是我可以只坚持使用angularjs?

谢谢.

解决方案

有一个关于从JavaScript代码在DOM中动态修改AngularJS内容的一般答案:

AngularJS + JQuery:如何获取动态内容在angularjs中工作

总而言之,当您从JavaScript代码中将ng-*属性放入DOM时,它们不会自动被关联;但是AngularJS提供了$compile函数,用于通过JavaScript的AngularJS属性连接新的HTML内容.

那么,对于Greasemonkey/Userscript,这意味着什么?

为此,我假设您的Greasemonkey脚本正在修改已经使用AngularJS的现有页面,并且您要添加的AngularJS内容使用了该页面上已存在的AngularJS范围中的某些变量或函数./p>

出于这些目的:

  1. 从AngularJS的动态注入系统中获取对$compile的引用
  2. 获取您想要将HTML代码连接到的AngularJS范围的参考
  3. 将具有ng-*属性的HTML代码放入字符串中,并在其和作用域上调用$compile.
  4. 获取结果,并使用通常的jQuery风格的方法将其放入页面中.

为了说明,这是 CERN的粒子点击器"游戏的小脚本,这会在工人"部分下添加一个统计信息.

$(function () { // Once the page is done loading...

   // Using jQuery, get the parts of the page we want to add the AngularJS content to
   var mediaList = $('ul.media-list');      
   var medias = $('li.media', mediaList);

   // A string with a fragment of HTML with AngularJS attributes that we want to add.
   // w is an existing object in the AngularJS scope of the
   // <li class="media"> tags that has properties rate and cost.
   var content = '<p>dps/MJTN = <span ng-bind="w.rate / w.cost * 1000000 | number:2"></span></p>';

   // Invoke a function through the injector so it gets access to $compile **
   angular.element(document).injector().invoke(function($compile) {

       angular.forEach(medias, function(media) {

           // Get the AngularJS scope we want our fragment to see
           var scope = angular.element(media).scope();

           // Pass our fragment content to $compile,
           // and call the function that $compile returns with the scope.
           var compiledContent = $compile(content)(scope);

           // Put the output of the compilation in to the page using jQuery
           $('p', media).after(compiledContent);

       });
   });

});

**注意:与使用依赖注入的所有AngularJS函数一样, .invoke使用传递给它的函数的参数名称 确定要注入的内容,如果您使用的是更改参数名称的压缩程序,则此操作会中断.

为避免这种情况,您可以更换

.invoke(function($compile) { ... });

格式

.invoke(['$compile', function($compile) { ... }]);

如果minifier将参数名称更改为$compile以外的其他名称,则不会中断.

I want to modify web pages' behavior using angularjs and greasemonkey. I want to know, what's the best way to do it? Should I use jquery to inject attributes like "ng-*" to DOM elements before I can write some angular code? Or can I solely stick to angularjs?

Thanks.

解决方案

There's a general answer about dynamically modifying AngularJS content in the DOM from JavaScript code here:

AngularJS + JQuery : How to get dynamic content working in angularjs

To sum up, when you put ng-* attributes into the DOM from JavaScript code, they won't automatically get hooked up; but AngularJS provides the $compile function for hooking up new HTML content with AngularJS attributes from JavaScript.

So what does this mean when it comes to Greasemonkey/Userscript?

For the purposes of this I'm assuming that your Greasemonkey script is modifying an existing page that already uses AngularJS, and the AngularJS content you want to add uses some of the variables or functions in AngularJS scopes already on that page.

For those purposes:

  1. Get a reference to $compile from AngularJS' dynamic injection system
  2. Get a reference to the AngularJS scope that you want your HTML code to be connected to
  3. Put your HTML code with ng-* attributes in a string and call $compile on it and the scope.
  4. Take the result of that and put it into the page using the usual jQuery-style ways.

To illustrate, here's a little script for CERN's Particle Clicker game, which adds a stat under the 'workers' section.

$(function () { // Once the page is done loading...

   // Using jQuery, get the parts of the page we want to add the AngularJS content to
   var mediaList = $('ul.media-list');      
   var medias = $('li.media', mediaList);

   // A string with a fragment of HTML with AngularJS attributes that we want to add.
   // w is an existing object in the AngularJS scope of the
   // <li class="media"> tags that has properties rate and cost.
   var content = '<p>dps/MJTN = <span ng-bind="w.rate / w.cost * 1000000 | number:2"></span></p>';

   // Invoke a function through the injector so it gets access to $compile **
   angular.element(document).injector().invoke(function($compile) {

       angular.forEach(medias, function(media) {

           // Get the AngularJS scope we want our fragment to see
           var scope = angular.element(media).scope();

           // Pass our fragment content to $compile,
           // and call the function that $compile returns with the scope.
           var compiledContent = $compile(content)(scope);

           // Put the output of the compilation in to the page using jQuery
           $('p', media).after(compiledContent);

       });
   });

});

** NB: Like any AngularJS function that uses its dependency injection, .invoke uses the parameter names of the function you pass to it determine what to inject, and this will break if you're using a minifier that changes the parameter names.

To avoid this you can replace

.invoke(function($compile) { ... });

with the form

.invoke(['$compile', function($compile) { ... }]);

which won't break if the minifier changes the parameter name to something other than $compile.

这篇关于如何将Angularjs与Gassmonkey一起使用来修改网页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆