2010-04-14 11 views
5

comment trouver des URLs (ie www.domain.com) dans un document, et les placer dans des ancres: < a href = "www.domain.com"> www.domain.com </a>Javascript: trouver des URLs dans un document

html:

Hey dude, check out this link www.google.com and www.yahoo.com! 

javascript:

(function(){var text = document.body.innerHTML;/*do replace regex => text*/})(); 

sortie:

Hey dude, check out this link <a href="www.google.com">www.google.com</a> and <a href="www.yahoo.com">www.yahoo.com</a>! 

Répondre

6

Tout d'abord, www.domain.com n'est pas une URL, il est un nom d'hôte, et

<a href="www.domain.com"> 

ne fonctionnera pas - il va chercher un fichier .com appelé www.domain par rapport à la page actuelle.

Il n'est pas possible de mettre en évidence les noms d'hôtes dans le cas général car presque tout peut être un nom d'hôte. Vous pourrait essayer de mettre en évidence «www.quelquechose.dot.separated.words», mais ce n'est pas vraiment fiable et il existe de nombreux sites qui n'utilisent pas le préfixe www. hostname. J'essaierais d'éviter ça.

/\bhttps?:\/\/[^\s<>"`{}|\^\[\]\\]+/; 

Ceci est un modèle très libéral que vous pouvez utiliser comme point de départ pour détecter les URL HTTP. Selon le type d'entrée que vous avez, vous voudrez peut-être affiner ce qu'il permet, et il peut être utile de détecter les caractères finaux comme . ou ! qui seraient des parties valides de l'URL, mais en pratique ne le sont généralement pas.

(Vous pouvez utiliser un | pour permettre soit la syntaxe URL ou la syntaxe www.hostname, si vous le souhaitez.)

Quoi qu'il en soit, une fois que vous avez installés sur votre modèle préféré, vous devrez trouver ce motif dans les nœuds de texte sur la page. Ne pas exécuter l'expression rationnelle sur le balisage innerHTML. Vous finirez par ruiner complètement la page en essayant d'annoter tous les href="http://something" qui sont déjà dans le balisage. Vous détruisez également les références JavaScript, les événements ou les valeurs de champs de formulaire existants lorsque vous remplacez le contenu innerHTML.

En général, regexp ne peut pas traiter le HTML de manière fiable. Profitez donc du fait que le navigateur a déjà analysé le code HTML en éléments et en nœuds de texte, et regardez simplement les nœuds de texte. Vous ne voulez pas non plus regarder à l'intérieur des éléments <a>, puisque baliser une URL comme un lien quand il est déjà dans un lien est idiot (et invalide).

// Mark up `http://...` text in an element and its descendants as links. 
// 
function addLinks(element) { 
    var urlpattern= /\bhttps?:\/\/[^\s<>"`{}|\^\[\]\\]+/g; 
    findTextExceptInLinks(element, urlpattern, function(node, match) { 
     node.splitText(match.index+match[0].length); 
     var a= document.createElement('a'); 
     a.href= match[0]; 
     a.appendChild(node.splitText(match.index)); 
     node.parentNode.insertBefore(a, node.nextSibling); 
    }); 
} 

// Find text in descendents of an element, in reverse document order 
// pattern must be a regexp with global flag 
// 
function findTextExceptInLinks(element, pattern, callback) { 
    for (var childi= element.childNodes.length; childi-->0;) { 
     var child= element.childNodes[childi]; 
     if (child.nodeType===Node.ELEMENT_NODE) { 
      if (child.tagName.toLowerCase()!=='a') 
       findTextExceptInLinks(child, pattern, callback); 
     } else if (child.nodeType===Node.TEXT_NODE) { 
      var matches= []; 
      var match; 
      while (match= pattern.exec(child.data)) 
       matches.push(match); 
      for (var i= matches.length; i-->0;) 
       callback.call(window, child, matches[i]); 
     } 
    } 
} 
Questions connexes