Adelson Anton wrote:
When you press, say Ctrl+K ( it doesn't matter which event), I want the
, say, second word in the document to be highlighted.
A rather difficult issue!
First, most js/DOM implementations define a word in a simplistic way,
using basic 26 latin letters; words can be more complicated than that,
using accentuated characters or non-latin charsets (without even
mentioning word-splitting issues).
Once you've defined which chars you're ready to accept as word token (or
which chars you wish to refuse), it's not too complicated (even
cross-browsers) to get the Nth word, either using ranges or DOM methods
(paying attention to block-level elements which should be considered as
a word delimiter). However, highlighting the found word is much more a
challenge, since this implies an analysis of the underlying DOM,
splitting nodes where necessary etc.
IE offers a powerful Range Model (much more text-oriented than the W3C
Range model), which makes it much easier, using a specific conception;
you'll find an example below, which should work on IE4+. I haven't
attempted to build a cross-browser script here since I just have a
week-end:-)
<style type="text/css">
..highlight{ background:yellow; }
</style>
<script type="text/javascript">
var highlightWord=(function(){
function isWordChar(c){
return new RegExp(
"^"+
"[\u0041-\u005A\u0061-\u007A\u00C0-\u00D6"+
"\u00D8-\u00F6\u00F8-\u00FF\u0100-\u017F"+
"\u0180-\u01BF\u01C4-\u0236]"+
"$"
).test(c);
}
return function(node, index){
var rng=document.body.createTextRange()
var inWord=false;
var wordCount=0;
var wordStart=0;
var wordLength=0;
var lineOffset=0; //for Windows' \r\n
var text;
function commit(){
rng.collapse(true);
rng.moveStart("character", wordStart-lineOffset);
rng.moveEnd("character", wordLength);
rng.pasteHTML("<span class='highlight'>"+rng.text+"<\/span>");
return rng;
}
rng.moveToElementText(node);
text=rng.text;
for(var ii=0; ii<text.length; ii++){
if(isWordChar(text.charAt(ii))){
if(!inWord){
wordCount++;
inWord=true;
wordStart=ii;
wordLength=1;
}else{
wordLength++;
}
} else {
if(inWord){
inWord=false;
} else {
if(text.charAt(ii)=="\u000A"&&text.charAt(ii-1)=="\u000D"){
lineOffset++;
}
}
}
if(wordCount==index && !inWord)
return commit();
}
if(wordCount==index)
return commit();
return null;
}
})();
function test(index){
if(document.body && document.body.createTextRange)
highlightWord(document.body, +index||0);
}
</script>
<div>Watch the sparrow fall</div>
<form>
<input type="text" name="wordIndex">
<input type="button"
value="test()"
onclick="test(this.form.wordIndex.value)">
</form>
HTH
Yep.