How do you define a word or choice throughout a document?

I am trying to highlight some of the text on my website. This selected text will be saved for a specific user in the database, and when the document is opened again, it will display the previously selected text. I assumed that I would use javascript to highlight the text, but I cannot find a way to determine where is the word that I highlight.

function getSelText() { var txt = ''; if (window.getSelection) { txt = window.getSelection(); } else if (document.getSelection) { txt = document.getSelection(); } else if (document.selection) { txt = document.selection.createRange().text; } else return ""; return txt; } 

I use this to get the selection, but I can't figure out where the selection is in the text. The biggest annoyance is when I have duplicates in a string or text, so if I were to use a search, I would find the first instance, not the one I was looking for.

So the question is: how do you define a word or choice throughout the document?

+8
javascript html
source share
3 answers

You can use my Rangy library and its serialization selector for this. The Rangy core provides a consistent selection and range API for all browsers, and the serializer module relies on this, converting each selection border into a path through the document. See the related documentation for more details.

+4
source share

This, of course, is not a trivial task, since you encounter two main problems finding text in the current document and then you can find it again the next time you load the page. The problem is even more complicated if the contents of your page can be changed, since you cannot even rely on the relative position of the text to remain unchanged.

You might want to consider whether this is the best approach to what you are trying to accomplish, given the required efforts, but here is something that can lead you in the right direction:

 function getSelection() { var selection, position; if (window.getSelection) { selection = window.getSelection(); if (selection && !selection.isCollapsed) { position = { 'offset': selection.anchorOffset, 'length': selection.toString().length, // We're assuming this will be a text node 'node': selection.anchorNode.parentNode }; } } else if (document.selection) { selection = document.selection.createRange(); if (selection && selection.text.length) { var text = selection.parentElement().innerText, range = document.body.createTextRange(), last = 0, index = -1; range.moveToElementText(selection.parentElement()); // Figure out which instance of the selected text in the overall // text is the correct one by walking through the occurrences while ((index = text.indexOf(selection.text, ++index)) !== -1) { range.moveStart('character', index - last); last = index; if (selection.offsetLeft == range.offsetLeft && selection.offsetTop == range.offsetTop) { break; } } position = { 'offset': index, 'length': selection.text.length, 'node': selection.parentElement() }; } } return position; } 

As well as the method for selecting text:

 function setSelection(position) { if (!position || !position.node) { return; } var selection, range, element; if (document.createRange) { element = position.node.childNodes[0]; range = document.createRange(); range.setStart(element, position.offset); range.setEnd(element, position.offset + position.length); selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } else if (document.body.createTextRange) { range = document.body.createTextRange(); range.moveToElementText(position.node); range.collapse(true); range.move('character', position.offset); range.moveEnd('character', position.length); range.select(); } } 

This code makes a rather naive assumption that the selected text is in the same DOM element. Most likely, if the user selects arbitrary text, this is not so.

Given that the Selection object takes this into account with the anchorNode and focusNode , you can try and work around this, although dealing with the TextRange object in Internet Explorer can be a bit more problematic.

There is also a problem with how to track the position.node value for page requests. In my jsFiddle example , I used a slightly modified version , creating a jQuery function to generate a selector that could be saved and used to re-select the correct node later. Note that the process is relatively trivial, so you can easily do this without jQuery - in this case, it just saved some effort.

Of course, if you change the DOM between visits, this approach is likely to be rather unstable. If you do not, I feel that this is probably one of the most reliable options.

+3
source share

createRange creates a textRange object. It has all the useful information:

  var range = document.selection.createRange(); var left = range.boundingLeft; var top = range.boundingTop; 
+1
source share

All Articles