2012-10-10 7 views
6

Więc mam kawałek HTML, który wygląda mniej więcej tak ...Korzystanie z jquery lub JS jak zmienić ciąg w link?

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

chcę przekręcić słowo cześć pod linkiem jQuery.

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

To samo w sobie nie jest zbyt trudne. Moim problemem jest to, że jeśli słowo jest już poza łącza jak na poniższym przykładzie ...

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

ja nie chcę skończyć z linkiem w linku ...

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

Każda pomoc będzie bardzo ceniona.

+0

Nie można po prostu zadzwonić do rodzica ("A") na elemencie tekstowym i zobacz, czy nie zwraca wartości null? – thatidiotguy

+0

Czy możesz opublikować kod, którego już używasz? – Jeff

Odpowiedz

0

Nie możesz przetestować elementu nadrzędnego słowa przed przekształceniem go w link?

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

(nie wiem, co rzeczywiste jQuery byłoby to sprawdzić)

EDIT

Poniższa zastąpi słowo we wszystkich <p> elementów, które nie zawierają link w nich.

Może nie działa dokładnie tak, jak wymagane, ale miejmy nadzieję punktów w kierunku

// 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>')); 

Live Demo on JSBin

+0

To jest mój problem, ja też nie wiem, jquery. Ponieważ wybierasz łańcuch (słowo Hello) zamiast elementu dom, nie wiem, w jaki sposób sprawdzasz jego bezpośredniego rodzica. –

0

Spróbuj .replace użytkownik funkcji jQuery coś takiego:

var str = $('p').html().replace('(some)','(to some)'); 
0

potrzebujesz jquery: not selektor lub .not().

Dokumenty API obejmują tę funkcję, powinieneś być w stanie wybrać swoją zawartość, a następnie odznacz odnośniki w jej obrębie.

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

1

Można zrobić to w ten sposób,

Live Demo

$('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>")); 
});​ 
0

Zamiast wyszukiwać słowa i próbuje znaleźć swoje rodzica, szukaj link i sprawdzić słowo to zawiera:

if($('a').text() === "hello"){ 
    //already linked 
}else{ 
    //not linked 
} 
0

Pierwszy zachować słowa podczas pozbycie bieżącego tagu zakotwiczenia, jeśli jest jedna:

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

następnie wykonaj wymienić na strunie, że trzeba pracować z

$('p').html($('p').text().replace('hello', '<a href="">hello</a>')); 
1

To rozwiązanie jQuery wyszukuje określony termin i nie tworzy linku, jeśli stwierdzi, że następuje tag zamykającego linku.

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); 
});​ 

Oto a link do jsfiddle dla niego.

+0

Zamknij, ale kończy się niepowodzeniem po dołączeniu do innego słowa, na przykład '

To jest kopia. W tym egzemplarzu słowo "is hello

" –

+0

@Vega Zmieniając się na twój przykład, to się powiedzie - ponieważ po hello następuje tag zamykający, a on powróci - zgodnie z życzeniem Paula. Jeśli jednak jest to "

To jest jakaś kopia. W tym egzemplarzu słowo "hello is

" zakończy się niepowodzeniem. Zaktualizowałem moje rozwiązanie, aby było w stanie obsłużyć to. –

1

Napisano prostą funkcję, aby sprawdzić, czy zastępowany tekst jest zawarty w tagu linku. Zobacz poniżej,

DEMO: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); 
     }   
    }); 
} 

Także nawet jeśli dodać zagnieżdżonego łącza przeglądarka po prostu zmienić go na dwie linki. Może być, ponieważ nie jest legalne używanie linków zagnieżdżonych. Patrz poniżej

udokumentowana także w W3C, dla Nested Links

12.2.2 zagnieżdżone łączy się nielegalna

linki i kotwy wyznaczonej przez wartości a element ten nie musi być zagnieżdżane; element A nie może zawierać żadnych innych elementów A.

Ponieważ DTD definiuje element LINK jako pusty, elementy LINK mogą nie być zagnieżdżone w elementach LINK .

I dlatego przeglądarka obsługuje zagnieżdżony link jako oddzielne linki.

http://jsfiddle.net/H44jE/

Zobacz Firebug wglądu na prawej dolnej części obrazu.

enter image description here

2

Trochę regex powinno wystarczyć (aktualizacja, patrz niżej):

$(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); 
     } 
    }); 
}); 

Fiddle: http://jsfiddle.net/G8rKw/

Edit: Ta wersja działa lepiej:

$(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); 
     } 
    }); 
}); 

Fiddle: http://jsfiddle.net/G8rKw/3/

Edycja ponownie: Tym razem, "hello" jest przekazywana jako zmienna do regex

$(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); 
     } 
    }); 
}); 

Fiddle: http://jsfiddle.net/webrocker/MtM3s/

+1

hm, wyrażenie regularne wymaga większej precyzji; jeśli jest "cześć" przed "word hello", to nie zostanie ono zastąpione, ponieważ _/(hello) (?!. *? <\/a>) _ będzie szukało "cześć", po którym nie następuje zamykająca etykieta - jakoś do tego wyrażenia musi być również dołączony znacznik otwierający , aby zatrzymać dopasowanie ... – Tom

+0

Dodano drugą wersję, która działa z kombinacjami wyszukiwań pierwotnych i bez linków w jednym akapicie. – Tom

+0

Dodano trzecią wersję, w której wyrażenie "hello" jest przekazywane jako zmienna w wyrażeniu regularnym. – Tom

Powiązane problemy