live highlight a word(s) with jQuery
I want to live hi开发者_开发技巧ghlight words with jQuery. I use a live keyup event to trigger the highlighting, so that the highlighting changes upon entering words(using a input text field for this)
I have found a piece of code which works fine but this code doesn't works with the live keyup event, so it wraps the first letter and stops there.
Here is my HTML:
<input type="text" id="input" name="input"/>
<div id="content-block"><p>lorem ip sum </p></div>
Here is my JS:
$('#input').live('keyup', function() {
$('#input').trigger('highLight');
});
$('#input').bind('highLight', function() {
var o = {words:$('input[name="input"]').val()};
highlight("content-block", o);
});
function highlight(id, options) {
var o = {
words: '',
caseSensitive: false,
wordsOnly: true,
template: '$1<span class="highlight">$2</span>$3'
},
pattern;
$.extend(true, o, options || {});
if (o.words.length == 0) { return; }
pattern = new RegExp('(>[^<.]*)(' + o.words + ')([^<.]*)', o.caseSensitive ? "" : "ig");
$('#'+id).each(function() {
var content = $(this).html();
if (!content) return;
$(this).html(content.replace(pattern, o.template));
});
}
The issue is that after the first successful replace the pattern now has to also match the ending span tag that has been inserted after the first matched character.
The HTML looks like this after entering "l":
<p><span class="highlight">l</span>orem ip sum</p>
"lorem" will no longer match because of the span.
Now with solution:
Here is a fix that should get it doing what you want:
$('#' + id).each(function() {
$('span.highlight',this).replaceWith($('span.highlight',this).text()); // Fix
var content = $(this).html();
if (!content) return;
$(this).html(content.replace(pattern, o.template));
});
Assuming that you will only have a single highlight span, the line below removes the span and replaces it with the text that it contained. Then the replace happens as normal.
$('span.highlight',this).replaceWith($('span.highlight',this).text()
A working example is here: http://jsfiddle.net/ryanrolds/N4DCR/
You should specify the global flag for your regular expression even if you are in case-sensitive mode. This is probably why only the first char gets replaced. Try using this:
pattern = new RegExp('(>[^<.]*)(' + o.words + ')([^<.]*)', (o.caseSensitive ? "" : "i") + "g");
精彩评论