Calculate Position of selected text javascript/JQuery?
Here's some simple, naive code to do this that may well do the job for your use case. It does not take into account any text that may be made invisible (either by CSS or by being inside a or element, for example) and may have browser discrepancies (IE versus everything else) with line breaks, and takes no account of collapsed whitespace (such as 2 or more consecutive space characters collapsing to one visible space on the page). However, it does work for your example in all major browsers.
Live demo: http://jsfiddle.net/UuDpL/2/
Code:
function getSelectionCharOffsetsWithin(element) {
var start = 0, end = 0;
var sel, range, priorRange;
if (typeof window.getSelection != "undefined") {
range = window.getSelection().getRangeAt(0);
priorRange = range.cloneRange();
priorRange.selectNodeContents(element);
priorRange.setEnd(range.startContainer, range.startOffset);
start = priorRange.toString().length;
end = start + range.toString().length;
} else if (typeof document.selection != "undefined" &&
(sel = document.selection).type != "Control") {
range = sel.createRange();
priorRange = document.body.createTextRange();
priorRange.moveToElementText(element);
priorRange.setEndPoint("EndToStart", range);
start = priorRange.text.length;
end = start + range.text.length;
}
return {
start: start,
end: end
};
}
alert( getSelectionCharOffsetsWithin(document.body).start );
Getting selected text position
The easiest way is to insert a temporary marker element at the start or end of the selection and get its position. I've demonstrated how to do this before on Stack Overflow: How can I position an element next to user text selection?
How to find index of selected text in getSelection() using javascript?
What you are looking for is available inside object returned by window.getSelection()
document.getElementById('ip').addEventListener('mouseup',function(e){ var txt = this.innerText; var selection = window.getSelection(); var start = selection.anchorOffset; var end = selection.focusOffset; if (start >= 0 && end >= 0){ console.log("start: " + start); console.log("end: " + end); }});
<div id="ip">YOLO Cobe</div>
Javascript find occurance position of selected text in a div
Assuming that the contents of the <div>
are guaranteed to be a single text node, this is not too hard. The following does not work in IE < 9, which does not support Selection and Range APIs. If you need support for these browsers, I can provide code for this particular case, or you could use my Rangy library.
Live demo: http://jsfiddle.net/timdown/VxTfu/
Code:
if (window.getSelection) {
var sel = window.getSelection();
var div = document.getElementById("content");
if (sel.rangeCount) {
// Get the selected range
var range = sel.getRangeAt(0);
// Check that the selection is wholly contained within the div text
if (range.commonAncestorContainer == div.firstChild) {
// Create a range that spans the content from the start of the div
// to the start of the selection
var precedingRange = document.createRange();
precedingRange.setStartBefore(div.firstChild);
precedingRange.setEnd(range.startContainer, range.startOffset);
// Get the text preceding the selection and do a crude estimate
// of the number of words by splitting on white space
var textPrecedingSelection = precedingRange.toString();
var wordIndex = textPrecedingSelection.split(/\s+/).length;
alert("Word index: " + wordIndex);
}
}
}
Get selected text position and place an element next to it
You could position a marker span at the end of the selection, get its coordinates using jQuery, place your button at those coordinates and remove the marker span.
The following should get you started:
var markSelection = (function() {
var markerTextChar = "\ufeff";
var markerTextCharEntity = "";
var markerEl, markerId = "sel_" + new Date().getTime() + "_" + Math.random().toString().substr(2);
var selectionEl;
return function(win) {
win = win || window;
var doc = win.document;
var sel, range;
// Branch for IE <= 8
if (doc.selection && doc.selection.createRange) {
// Clone the TextRange and collapse
range = doc.selection.createRange().duplicate();
range.collapse(false);
// Create the marker element containing a single invisible character by creating literal HTML and insert it
range.pasteHTML('<span id="' + markerId + '" style="position: relative;">' + markerTextCharEntity + '</span>');
markerEl = doc.getElementById(markerId);
} else if (win.getSelection) {
sel = win.getSelection();
range = sel.getRangeAt(0).cloneRange();
range.collapse(false);
// Create the marker element containing a single invisible character using DOM methods and insert it
markerEl = doc.createElement("span");
markerEl.id = markerId;
markerEl.appendChild( doc.createTextNode(markerTextChar) );
range.insertNode(markerEl);
}
if (markerEl) {
// Lazily create element to be placed next to the selection
if (!selectionEl) {
selectionEl = doc.createElement("div");
selectionEl.style.border = "solid darkblue 1px";
selectionEl.style.backgroundColor = "lightgoldenrodyellow";
selectionEl.innerHTML = "<- selection";
selectionEl.style.position = "absolute";
doc.body.appendChild(selectionEl);
}
// Find markerEl position http://www.quirksmode.org/js/findpos.html
var obj = markerEl;
var left = 0, top = 0;
do {
left += obj.offsetLeft;
top += obj.offsetTop;
} while (obj = obj.offsetParent);
// Move the button into place.
// Substitute your jQuery stuff in here
selectionEl.style.left = left + "px";
selectionEl.style.top = top + "px";
markerEl.parentNode.removeChild(markerEl);
}
};
})();
Related Topics
Canvas.Todataurl() Security Error the Operation Is Insecure
Getelementbyclass().Setattribute Doesn't Work
How to Find Which JavaScript Is Changing an Element's Style
Hiding Div If Using Mobile Browser
Invert Filter Not Working on Ie and Safari
How to Make the Facebook Like Button's Width Automatically Resize
Images Are Being Rotated by Default Upon Upload
Fastest Selector Method in Jquery and CSS - Id or Not
Find Td with Specific Text, and Operate on the Td Right After That One
Fixed/Absolute Positioning Neglected in iOS When Focusing on Input
Handling "Onclick" Event with Pure JavaScript
Size of Createelement("Svg") Is 0,0
Can JavaScript Change the Value of @Page CSS
How to Change the Style of Elements with Same Class Name
Cannot Apply Any Bootstrap Style in Using React-Bootstrap Library
How to Generate Random Pastel (Or Brighter) Color in JavaScript
Blinking Fixed Header in Site with Scrolling Animation
Is It Normal to Have Two Elements with Same Id in Two Div Elements with Other Id