Agregue dinámicamente etiquetas de anclaje alrededor del texto SIN volver a escribir el HTML

I'm using javascript, jQuery and regex to add anchors (#hashtag) around all hashtags on the page. The regex detects things that are hashtags, and then I use jQuery to re-write the HTML and a javascript .replace() to add in the anchor tags. I also do a javascript if statement so it doesn't replace things inside of script and style tags.

var regExp = /(\W)#([a-zA-Z_]+)(\W)/gm;
var boxLink = "$1<a class='tagLink' onClick=\"doServer('#$2')\">#$2</a>$3"
$('body').children().each(function(){

if (($(this).get(0).tagName.toLowerCase() != 'style') 
 && ($(this).get(0).tagName.toLowerCase() != 'script') 
) {
    $(this).html($(this).html().replace(regExp, boxLink));
  }
  });
});

Simple enough... right?

El problema es que that I'm making a plugin, so developers will deploy this on their websites. The html rewrite ($(this).html($(this).html().replace(regExp, boxLink));) breaks seemingly random areas of javascript on websites. It also messes up some HTML structure sometimes. It's just a really messy thing to be doing on lots of different sites.

So rather then fix the re-write, I'd like to just find another way to do this. Is there any way I can accomplish the same thing (adding anchor tags around all hashtags on the page) without re-writing the entire HTML on the page each load?

If not, how can I tweak the javascript I have so it isn't so conflicting with javascript on people's sites.

preguntado el 01 de febrero de 12 a las 04:02

2 Respuestas

This replaces every textnode con un hashtag on this page with:

<span>texts without hash <a name = "myplugin">#</a></span>

You can substitute the regex to match yours :)

var getTextNodesIn = function(el) {
    $(el).find("*").andSelf().contents().each(function() {
        var parentNode = this.parentNode.nodeName,
            data = this.data;
        if(this.nodeType == 3 && parentNode !== "SCRIPT" && parentNode !== "STYLE" && data.indexOf("#") > -1){
            var anch = data.replace(/#/g,"#".anchor("myplugin")); 
            $(this).replaceWith("<span>"+anch+"<span/>");
        }
    });
};

getTextNodesIn(document.body);

PS getTextNodesIn function was taken from this post :

https://stackoverflow.com/a/4399718/776575

contestado el 23 de mayo de 17 a las 15:05

Nothing in the console, but it doesn't highlight any tags. I've tried debugging, can't see the issue. Here's a site I have it deployed on with your snippet: jacksongariety.com/blog - alt

Your snippet is in the file called "script.js" loading in the footer. - alt

Through the web inspector i see <span><a name="myplugin">#</a>hashtag <a name="myplugin">#</a>testing <a name="myplugin">#</a>words<span></span></span> . So it works fine.. You only need to add your regex - Richard A

How can I get it to include the whole word? Right not it only puts the # in the anchor. - alt

Maybe just do data.anchor("myplugin"); más bien que data.replace(/#/g,"#".anchor("myplugin")); - Richard A

I think part of the problem is that you need to isolate the text nodes and operate on those, not chunks of html. Your example only iterates across the direct children of body, but then tries to apply replacements to whatever html is within those children. This could easily cause existing markup and javascript to break.

Answers to question might be helpful: ¿Cómo selecciono nodos de texto con jQuery?

contestado el 23 de mayo de 17 a las 15:05

So I should filter out text nodes? But in order to add he <a> I still have to do a .replace() right? Doesn't that require re-writing of the HTML? - alt

Also, if I showed you the whole javascript file and page it is operating on, think you could show me how I could incorporate selecting the text nodes? - alt

I'm not convinced "re-writing" the html is causing your problem. Because you're applying your replacement on what could be a block of html, there's nothing preventing it from matching against <a href="somewhere/#here">, or something similar. Might that be what's breaking things? If you limit your transformations to text nodes you won't have this problem. - dellsala

Would I do a document.write($(textnodes).replace(regexp, boxlink)), that is assuming I have a variable that returns all the text nodes? - alt

I think when I do the re-writing of the HTML, it strips the event listeners. I can't get that function working either though. - alt

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.