How do I highlight and save text in HTML using JavaScript? - javascript

I want to highlight text and save the selection so that next time I view the page, it will display with the same text highlighted.
I tried to get the index of selected text but the index is related only to the HTML tag, not related to all the page text. This is what I have:
<script>
function highlight() {
range = window.getSelection();
var st = range.anchorOffset;
var en = range.focusOffset - range.anchorOffset;
alert(st);
alert(en);
}
</script>
I don't know how to get selected text attributes which can help me to save my highlight in the next open to the HTML file.

Here's what I found. For reference, here is a good post about this topic.
JSFiddle
JS:
var copiedText = "";
$(function(){
$("button").click(function(event){
getSelectionText();
alert(copiedText);
});
});
function getSelectionText() {
if (window.getSelection) {
copiedText = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
copiedText = document.selection.createRange().text;
}
}

Related

Add element w/ text node after user selection

I have the following function that creates a new text node at the end of a document when called, using the value of text within a text field:
function addAfter () {
var elem = document.getElementById('textfield').value;
var h = document.createElement('span');
var t = document.createTextNode(elem);
h.appendChild(t);
document.body.appendChild(h);
}
What I would like it to do would be to add the text immediately after user-selected text (like when you click and drag to select text). What needs to replace the document.body.appendChild(h); for this to work?
Try This JS Fiddle
This should do it on anything but IE edge(I believe)
function getSelectionText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}
document.body.addEventListener('mouseup', function() {
(window.getSelection()) ? addText(window.getSelection().toString(), window.getSelection().baseNode.parentNode) : addText(document.selection.toString(), document.selection.baseNode.parentNode);
});
function addText(text, parent) {
parent.appendChild(document.createTextNode(text));
}
The way that this works is it uses the mouseUp event to determine whether or not text MAY have been selected. Selected text is stored underneath window.getSelected() OR document.selected() - it then passes that value as well as the parent of the selected text to the addText function. It uses the document appendChild and createTextNode methods to append the captured text to the DOM.
In Previous Versions of IE they used document.select(), but in Edge they switched over to getSelection(like everyone else) BUT they didn't implement the same value that's returned when you get text, ergo you can't really grab the parentNode and easily append to that node.
So, in short, this will give you what you're looking for, but it's not cross-browser and there doesn't appear to be a way to do that easily.
I manipulated a solution that I found on another feed.
function addAfter (isBefore) {
var sel, range, node;
var changeText = document.getElementById('textfield').value;
var textAndCode = "<span class=\"correction\"> " + changeText + " </span>";
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = window.getSelection().getRangeAt(0);
range.collapse(isBefore);
// Range.createContextualFragment() would be useful here but was
// until recently non-standard and not supported in all browsers
// (IE9, for one)
var el = document.createElement("div");
el.innerHTML = textAndCode;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.collapse(isBefore);
range.pasteHTML(textAndCode);
}
}
You just have to pass in the value for isBefore as false if you want it to appear after.

Javascript edit text in selection via Bookmarklet

I am trying to make a simple bookmarklet (bookmark with javascript applet) that will get the selected text, reverse it, and then change it on screen. For example, if the user selects some text, say, the word hello, and then activates this bookmarklet, the text would then turn into olleh. So far I have the following:
javascript:
function getSelectedText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}
var selectedText = getSelectedText();
var textArray = selectedText.split("");
var reverseArray = textArray.reverse();
var reverseText = reverseArray.join("");
alert(reverseText);
I got the getSelectedText() function from here. At the end, the bookmarklet simply alerts the reversed text. How do you make it so that it actually replaces the text on the page? Thanks in advance for any possible help.
You can add this to the end:
var nodeValue = window.getSelection().baseNode.nodeValue;
window.getSelection().baseNode.nodeValue = nodeValue.replace(selectedText, reverseText);
EDIT
Use selection offset for reversing in the right place, str.replace only replaces the first occurrence of the word, and it can be wrong for common words such as "the".
var selection = window.getSelection();
var start = selection.anchorOffset;
var end = selection.focusOffset;
var nodeValue = selection.baseNode.nodeValue;
var newValue = nodeValue.slice(0, start) + reverseText + nodeValue.slice(end);
window.getSelection().baseNode.nodeValue = newValue;

Highlight text in javascript like Evernote Web Clipper

My current solution is:
Get selected html (include text and html tag), namely: selText
highlightText = <span>selText</span>
Find selText in innerHTML of the body or document (or the element which the mouse dragged in)
Replace with highlightText
But if the document is: a a a a a a and user selects the last a. My function will highlight the first or all a.
Any suggestion?
Thank you.
i think your question is duplicated, anyway i just searched the internet and found this article.
Below the final code to achieve what you ask
function highlightSelection() {
var selection;
//Get the selected stuff
if(window.getSelection)
selection = window.getSelection();
else if(typeof document.selection!="undefined")
selection = document.selection;
//Get a the selected content, in a range object
var range = selection.getRangeAt(0);
//If the range spans some text, and inside a tag, set its css class.
if(range && !selection.isCollapsed)
{
if(selection.anchorNode.parentNode == selection.focusNode.parentNode)
{
var span = document.createElement('span');
span.className = 'highlight-green';
range.surroundContents(span);
}
}
}
I also found this library rangy that is an helper you can use to select text but only works with jquery so i prefer the first vanilla-js solution.
var el = $("<span></span>");
el.text(rangy.getSelection().getRangeAt(0).toString());
rangy.getSelection().getRangeAt(0).deleteContents();
rangy.getSelection().getRangeAt(0).insertNode(el.get(0));
rangy.getSelection().getRangeAt(0).getSelection().setSingleRange(range);
On Range and User Selection
You have to select range using Document.createRange that return a Range object before you can use Range.surroundContents(), you could create a range this way.
var range = document.createRange();
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);
In practice you follow this guide to understand range and selection tecniques.
The most important point is contained in this code
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
}
else if (document.selection) { // should come last; Opera!
userSelection = document.selection.createRange();
}
After this you can use
userSelection.surroundContents()

How can I toggle a class on selected text?

I'm trying to create a fairly simple text editor (bold, italic, indent) and need to be able to toggle the class associated with the button on click. I have this code:
var selected = function ()
{
var text = '';
if (window.getSelection) {
text = window.getSelection();
}
return text;
}
$('textarea').select(function(eventObject)
{
console.log(selected().toString());
var selectedtext = selected().toString();
$('#bold-button').click(function () {
$(selectedtext).addClass('bold-text');
});
});
And I can get the selected text to print, but can't get the class added. I've seen other solutions that add the class on click to the entire textarea, but I dont need that. Any help?
You could use surroundContents() like below. Before demo here http://jsfiddle.net/jwRG8/3/
function surroundSelection() {
var span = document.createElement("span");
span.style.fontWeight = "bold";
span.style.color = "green";
if (window.getSelection) {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(span);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
But this is not supported less than IE9. And I worked on text selections before and I found them in consistent. Tim Down is very much experienced on selections and most of the answers in SO related to Selections are given my him. He has written a plugin called rangy. You mat try it at https://code.google.com/p/rangy/
Because you are selecting text directly, there is no element to add the class on. textNodes cannot have classes. Instead, try wrapping the text in an element:
$('textarea').select(function(eventObject) {
console.log(selected().toString());
var selectedtext = selected().toString();
$(selectedtext).wrap('<span />').parent().addClass('bold-text');
})
Or you could just wrap it in a b tag, without the class:
$(selectedtext).wrap('<b/>');

Finding indices of highlighted text

I'm trying to save information about text that a user has highlighted in a webpage. Currently I'm using the getSelection method shown below:
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;
to retrieve the highlighted text. Then I'm searching through the entire text body and storing the indices of the highlighted text. The getSelection method only returns what text is highlighted so the problem is that if the highlighted text appears multiple times in the text body, the search could find the wrong repeat of the text and thus save the wrong indices.
Any ideas how to ensure that I'm saving the right indices?
Thanks!
QuirksMode has an article about this.
You'd probably be interested in this code:
var userSelection;
if (window.getSelection) {
userSelection = window.getSelection();
}
else if (document.selection) { // should come last; Opera!
userSelection = document.selection.createRange();
}
var rangeObject = getRangeObject(userSelection);
function getRangeObject(selectionObject) {
if (selectionObject.getRangeAt)
return selectionObject.getRangeAt(0);
else { // Safari!
var range = document.createRange();
range.setStart(selectionObject.anchorNode,selectionObject.anchorOffset);
range.setEnd(selectionObject.focusNode,selectionObject.focusOffset);
return range;
}
}

Categories

Resources