2010-10-16 22 views
1

我想修改日期形式的文档中的文本,并将其替换为链接以将该日期的活动添加到Google日历。我主要有这个工作,一个警告,它试图添加已有链接,其中有日期的链接。只替换网页上的文本以创建链接

document.body.innerHTML = document.body.innerHTML.replace(arrayDates[i], arrayDates[i] + " <a href=\"http://www.google.com/calendar/event?action=TEMPLATE&text=someevent&dates=" + dateString + "&details=&location=&trp=false&sprop=&sprop= target=\"_blank\"> <img src=\"" + chrome.extension.getURL("Config-date-16.png") + "\" title=\"Add this event to your Google Calendar\"> </a> "); 

我以为只是运行在所有p标签元素的innerHTML字符串替换:如

arrayP = document.body.getElementsByTagName("p"); 
for(i=0;i<arrayP.length:i++) { 
    arrayP[i].innerHTML = arrayP[i].innerHTML.replace(arrayDates[i], arrayDates[i] + " <a href=\"http://www.google.com/calendar/event?action=TEMPLATE&text=someevent&dates=" + dateString + "&details=&location=&trp=false&sprop=&sprop= target=\"_blank\"> <img src=\"" + chrome.extension.getURL("Config-date-16.png") + "\" title=\"Add this event to your Google Calendar\"> </a> "); 
} 

而且这也包括儿童(如链接标签)。我不确定如何在没有孩子的情况下只替换p标签元素的innerHTML。

除了删除带有标签的所有元素(它也会破坏图像等,所以我应该对这些元素也做同样的事情),运行替换,并重新插入标签元素,我想不出另一种方式已经存在的链接问题(想法欢迎)。

不幸的是我也遇到了这个问题。我可以使用正则表达式来匹配innerHTML字符串中的所有元素,但是我认为使用DOM会更简单。

我尝试了以下,但我不知道如何解决不知道哪个孩子tobeReplacedNodes [i]属于的问题:(编辑:我大概可以调用.parent或somesuch来弄清楚它是什么父母是...我会再次尝试了这一点,并报告是怎么回事

tobeReplacedNodes = document.body.getElementsByTagName("a"); 
for(i=0;i<tobeReplacedNodes.length;i++) { 
    tobeReplacedNodes[i] = document.body.replaceChild(element, tobeReplacedNodes[i]); 
} 

我至今在这里:http://code.google.com/p/calendar-event-adder/(测试分支是最电流)

任何想法/感谢您的建议,谢谢!

回答

1

递归地走DOM,跳过链接(及其子节点),并仅处理nodeType"text"的节点。您应该在包含文本的所有内容中包含Text节点,其中包括<p>

2

而不是对整个文档做一个RegExp,我会尝试使用DOM。

使用jQuery,我首先只选择我想替换文本节点的节点。这很重要,否则你也会替换你真正想要避免的标签中的内容,例如<code>或事件<script>。在那些获得文本节点并提取匹配。我的例子在选择要考虑扫描的元素YMMV方面非常保守。

// I used this code to execute on your stackoverflow question, 
// thus I choose "this" . Try it in Firebug. 
var re = /(this)/gi, split; 
$('div,p').contents().each(function() { 
    if (this.nodeType == Node.TEXT_NODE) { 
     if (this.nodeValue.match(re)) { 
      split = this.nodeValue.split(re); 
      for (var i = 0, l = split.length; i < l; i++) { 
       if (i % 2) { 
        // the re catches the match thus every 
        // odd index is the match 
        $('<a href="#destination">' + split[i] + 
         '</a>').insertBefore(this); 
       } else { 
        $(document.createTextNode(split[i])). 
         insertBefore(this); 
       } 
      } 
      $(this).remove(); 
     } 
    } 
}); 

据我所知使用Node.TEXT_NODE是不是跨浏览器兼容,使用原生值3如果它不是可用可能是必要的。我也读过String#split也许不适用于任何地方。换句话说:需要仔细测试。

+0

谢谢。我使用了你的解决方案和Edgars解决方案的一部分,并提出了一个(不是100%完成的,我需要匹配文本节点中的文本,然后创建一个链接元素并将其附加为文本节点子节点,从而摆脱不正确的data.replace)可能效率较低的解决方案。总之,这里是我有什么(我通过在body元素)到目前为止,我一次,我完成后再次:(不全部装入此评论)pastebin.com/RmHk3sKk 我会投你,埃德加了,但我还没有足够的声望,我不确定谁选择作为接受的解决方案,因为这两个都是ri – 2010-10-18 10:16:23

+0

@Thomas:你的pastie代码有可能通过非web -text节点,因为你用'hasChildNodes'其中*可能*找到''