7

所以我有一段看起来像这样的HTML......

<p>This is some copy. In this copy is the word hello</p>

我想将单词 hello 变成使用 jquery 的链接。

<p>This is some copy. In this copy is the word <a href="">hello</a></p>

这本身并不太难。我的问题是,如果这个词已经是一个链接的一部分,比如下面的例子......

<p>In this copy is the <a href="">word hello</a></p>

我不希望以链接中的链接结束...

<p>In this copy is the <a href="">word <a href="">hello</a></a></p>

任何帮助将非常感激。

4

9 回答 9

3

一点正则表达式应该可以解决问题(更新,见下文):

$(document).ready(function(){
    var needle = 'hello';
    $('p').each(function(){
        var me = $(this),
            txt = me.html(),
            found = me.find(needle).length;
        if (found != -1) {
            txt = txt.replace(/(hello)(?!.*?<\/a>)/gi, '<a href="">$1</a>');
            me.html(txt);
        }
    });
});

小提琴:http: //jsfiddle.net/G8rKw/

编辑:这个版本效果更好:

$(document).ready(function() {
    var needle = 'hello';
    $('p').each(function() {
        var me = $(this),
            txt = me.html(),
            found = me.find(needle).length;
        if (found != -1) {
            txt = txt.replace(/(hello)(?![^(<a.*?>).]*?<\/a>)/gi, '<a href="">$1</a>');
            me.html(txt);
        }
    });
});

小提琴:http: //jsfiddle.net/G8rKw/3/

再次编辑:这一次,“hello”作为变量传递给正则表达式

$(document).ready(function() {
    var needle = 'hello';
    $('p').each(function() {
        var me = $(this),
        txt = me.html(),
        found = me.find(needle).length,
        regex = new RegExp('(' + needle + ')(?![^(<a.*?>).]*?<\/a>)','gi');
        if (found != -1) {
            txt = txt.replace(regex, '<a href="">$1</a>');
            me.html(txt);
        }
    });
});

小提琴:http: //jsfiddle.net/webrocker/MtM3s/

于 2012-10-10T16:47:30.543 回答
1

你可以这样做,

现场演示

$('p').each(function(){    
    if($(this).find('a').length > 0) return;  
    lastSpaceIndex = $(this).text().lastIndexOf(' ');
    if(lastSpaceIndex  == -1)
        lastSpaceIndex = 0;    
    WordToReplace = $(this).text().substring(lastSpaceIndex);
    idx = $(this).text().lastIndexOf(WordToReplace);
    resultstring = $(this).text().substring(0, idx); 
    $(this).html(resultstring);
    $(this).append($( "<a href='#'>" + WordToReplace  + "</a>"));
});​
于 2012-10-10T14:23:19.397 回答
1

此 jQuery 解决方案搜索特定术语,如果发现它后面跟着一个结束链接标记,则不会创建链接。

var searchTerm = "hello";

$('p:contains("' + searchTerm + '")').each(function(){
    var searchString = $(this).html();
    var searchIndex = searchString.indexOf(searchTerm);
    var startString = searchString.substr(0 , searchIndex);
    var endString = searchString.substr(searchIndex + searchTerm.length);
    if(endString.match(/<\/a>/g)) return;
    $(this).html(startString + "<a href=''>" + searchTerm + "</a>" + endString);
});​

这是一个 jsfiddle的链接。

于 2012-10-10T15:32:46.910 回答
1

编写了一个简单的函数来检查替换文本是否包含在链接标记中。见下文,

演示:http: //jsfiddle.net/wyUYb/4/

function changeToLink (sel, txt) {
   var regEx = new RegExp(txt, 'g');
   $.each($(sel), function (i, el) {
       var linkHTML = $(el).html();
       var idx = linkHTML.indexOf(txt);

       if (idx >= 0) {
           var t = linkHTML.substring(idx);
           //Fix for IE returning tag names in upper case http://stackoverflow.com/questions/2873326/convert-html-tag-to-lowercase
           t = t.replace(/<\/?[A-Z]+.*?>/g, function (m) { return m.toLowerCase(); })
           var closingA = t.indexOf('</a>');

           t = t.substring(0, closingA);
           if (closingA != -1) {
               t = t.substring(0, closingA); 
               if (t.indexOf('<a') < txt.length) {
                   return;
               }
           }               

           linkHTML = linkHTML.replace(regEx, '<a href="">' + txt + '</a>');
           $(el).html(linkHTML);
       }           
   });
}

此外,即使您添加一个嵌套链接,您的浏览器也会简单地将其更改为两个链接。可能是因为使用嵌套链接是不合法的。见下文,

在 W3C 中也记录了嵌套链接

12.2.2 嵌套链接是非法的

A 元素定义的链接和锚点不得嵌套;A 元素不得包含任何其他 A 元素。

由于 DTD 将 LINK 元素定义为空,因此 LINK 元素也不能嵌套。

这就是浏览器将嵌套链接作为单独链接处理的原因。

http://jsfiddle.net/H44jE/

请参阅图像右下角的萤火虫检查。

在此处输入图像描述

于 2012-10-10T15:32:48.753 回答
0

不要搜索单词并尝试查找其父项,而是搜索链接并检查其中包含的单词:

if($('a').text() === "hello"){
  //already linked
}else{
  //not linked
}
于 2012-10-10T14:24:44.533 回答
0

先保留单词,同时去掉当前的锚标签,如果有的话:

$('a').each(function() {
    $(this).replaceWith(this.childNodes);
 });

然后对您需要使用的字符串进行替换

$('p').html($('p').text().replace('hello', '<a href="">hello</a>'));
于 2012-10-10T15:12:13.323 回答
0

您需要 jquery :not 选择器或 .not()。

API 文档很好地涵盖了这一点,您应该能够选择您的内容,然后取消选择其中的链接。

http://api.jquery.com/not-selector/

于 2012-10-10T14:21:05.210 回答
0

尝试用户 .replace jquery 函数是这样的:

var str = $('p').html().replace('(some)','(to some)');
于 2012-10-10T14:08:35.727 回答
0

在将单词转换为链接之前,您不能测试单词的父元素吗?

if (parent != 'a') {
   // do your thing
}

(我不知道实际的 jQuery 会测试这个)

编辑

以下将替换所有<p>不包含链接的元素中的单词。

可能无法完全按照要求工作,但希望为您指明方向

// get all p elements that contain the word hello but DO NOT have link in them
var elems = $('p:contains("hello")').not(':has(a)');


// replace instances of hello in the selected p elements
$(elems).html($(elems).html().replace(/(hello)/g,'<a href="new">$1</a>'));

JSBin 上的现场演示

于 2012-10-10T14:07:56.163 回答