如何用greasemonkey修改CDATA?

时间:2012-11-13 21:12:37

标签: javascript greasemonkey cdata

有一个网页包含使用Javascript制作的所有HTML结构。例如:

<script language="JavaScript" type="text/javascript">
//<![CDATA[
function abcd()
{
document.writeln('<div id="abc">');
document.writeln('<div class="Wrapper">');
document.writeln('Test');
...
}
</script>

我想要做的是用Test替换单词<b>Test</b>的所有实例,但我不确定我是如何以这种方式获取元素/ HTML的。

1 个答案:

答案 0 :(得分:1)

您想要包装Test,并通过javascript添加有问题的HTML。如果是这样,那么有三种基本方法:

  1. 您可以只显示目标字词。这是最强大的方法。有关详细信息,请参见下文。

  2. 您经常可以在以后重写有问题的javascript函数。例如:

    // ==UserScript==
    // @name     YOUR_SCRIPT_NAME
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/*
    // ==/UserScript==
    
    function abcd () {
        document.writeln('<div id="abc">');
        document.writeln('<div class="Wrapper">');
        document.writeln('<b>Test</b>');
        ...
    }
    
    var D                   = document;
    var scriptNode          = D.createElement ('script');
    scriptNode.type         = "text/javascript";
    scriptNode.textContent  = abcd;
    
    var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
    


    将取代邪恶版本的abcd (),希望在它运行之前。

  3. 您可以尝试在加载之后和执行之前拦截该<script>节点(一旦脚本运行,更改源将无效)。

    使用Firefox可以实现这一点,请参阅this answer了解Greasemonkey代码。不过,在这种情况下,我不建议采用这种方法。

  4. CDATA不是任何这些方法的因素。



    显示目标文本:

    1. 使用the waitForKeyElements() utility捕获感兴趣的节点。没有必要分析页面的javascript或担心可能会破坏某些内容的更改。

    2. 使用常见的DOM方法来包装目标文本,而不会破坏HTML或破坏事件侦听器。在这种情况下,它是wrapTextWithElement对象。

    3. jQuery让一切变得更轻松,更清晰。

    4. 这是完整脚本。您也可以针对this demo page进行测试。

      // ==UserScript==
      // @name     YOUR_SCRIPT_NAME
      // @include  http://fiddle.jshell.net/gH4nV/*
      // @include  http://YOUR_SERVER.COM/YOUR_PATH/*
      // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
      // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
      // @grant    GM_addStyle
      // ==/UserScript==
      /*- The @grant directive is needed to work around a design change introduced
          in GM 1.0.   It restores the sandbox.
      */
      
      waitForKeyElements ("div.Wrapper", emboldenTheWordTest);
      
      function emboldenTheWordTest (jNode) {
          var testWrapper = new wrapTextWithElement ('Test', '<b>');
          testWrapper.wrap (jNode);
      }
      
      function wrapTextWithElement (targText, elemToWrapWith, bCaseSensitive) {
          var self            = this;
          var bCaseSensitive  = bCaseSensitive || false;
          self.targRegEx      = new RegExp ("(" + targText + ")", bCaseSensitive ? "" : "i");
          self.elemToWrapWith = elemToWrapWith;
      
          self.wrap = function (node) {
              $(node).contents ().each ( function () {
                  if (this.nodeType === Node.ELEMENT_NODE) {
                      self.wrap (this);
                  }
                  else if (this.nodeType === Node.TEXT_NODE) {
                      var ndText  = this.nodeValue;
      
                      if (self.targRegEx.test (ndText) ) {
                          var replaceNodes = $.map (
                              ndText.split (self.targRegEx),
                              function (phrase) {
                                  if (self.targRegEx.test (phrase) ) {
                                      var wrapped = $(self.elemToWrapWith, {text: phrase} );
      
                                      return wrapped.get ();
                                  }
                                  else {
                                      if (phrase == "")
                                          return null;
                                      else
                                          return document.createTextNode (phrase)
                                  }
                              }
                          );
                          $(this).replaceWith (replaceNodes);
                      }
                  }
              } );
          };
      }