开发者

how to use js to do very basic syntax coloring?

here's a very simple js but i don't know where to begin.

in a html page, if some text is enclosed by angle brackets, like this:

〈some text〉

i want the text to be colored (but not the brackets).

in normal html, i'd code it like this

〈<span class="booktitle">some text<开发者_运维百科/span>〉

So, my question is, how do i start to write such a js script that search the text and replace it with span tags?

some basic guide on how to would be sufficient. Thanks. (i know i need to read the whole html, find the match perhaps using regex, then replace the page with the new one. But have no idea how that can be done with js/DOM. Do i need to traverse every element, get their inner text, do possible replacement? A short example would be greatly appreciated.)


It depends partially on how cautious you need to be not to disturb event handlers on the elements you're traversing. If it's your page and you're in control of the handlers, you may not need to worry; if you're doing a library or bookmarklet or similar, you need to be very careful.

For example, consider this markup:

<p>And <a href='foo.html'>the 〈foo〉 is 〈bar〉</a>.</p>

If you did this:

var p = /* ...get a reference to the `p` element... */;
p.innerHTML = p.innerHTML.replace(/〈([^〉]*)〉/g, function(whole, c0) {
    return "〈<span class='booktitle'>" + c0 + "</span>〉";
});

(live example) (the example uses unicode escapes and HTML numeric entities for 〈 and 〉 rather than the literals above, because JSBin doesn't like them raw, presumably an encoding issue)

...that would work and be really easy (as you see), but if there were an event handler on the a, it would get blown away (because we're destroying the a and recreating it). But if your text is uncomplicated and you're in control of the event handlers on it, that kind of simple solution might be all you need.

To be (almost) completely minimal-impact will require walking the DOM tree and only processing text nodes. For that, you'd be using Node#childNodes (for walking through the DOM), Node#nodeType (to know what kind of node you're dealing with), Node#nodeValue (to get the text of a text node), Node#splitText (on the text nodes, to split them in two so you can move one of them into your span), and Node#appendChild (to rehome the text node that you need to put in your span; don't worry about removing them from their parent, appendChild handles that for you). The above are covered by the DOM specification (v2 here, v3 here; most browsers are somewhere between the two; the links in the text above are to the DOM2 spec).

You'll want to be careful about this sort of case:

<p>The 〈foo <em>and</em> bar〉.</p>

...where the 〈 and the 〉 are in different text nodes (both children of the p, on either side of an em element); there you'll have to move part of each text node and the whole of the em into your span, most likely.

Hopefully that's enough to get you started.


If the text could be anywhere in the page, you have to traverse through each DOM element, split the text when you found a match using a regex.

I have put my code up there on jsfiddle: http://jsfiddle.net/thai/RjHqe/

What it does: It looks at the node you put it in,

  • If it's an element, then it looks into every child nodes of it.
  • If it's a text node, it finds the text enclosed in 〈angle brackets〉. If there is a match (look at the first match only), then it splits the text node into 3 parts:

    • left (the opening bracket and also text before that)
    • middle (the text inside the angle bracket)
    • right (the closing bracket and text after it)

    the middle part is wrapped inside the <span> and the right part is being looked for more angle brackets.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜