Getting Selected Text Position

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>

How to get highlighted text position from textarea?

This will work for text selection with the mouse and keyboard for all <textarea> elements on the page.
Change the selector (be more specific) if you don't want all <textarea> elements to have this text selection.

Read the comments, you will find out there how to disable keyboard selection, if you don't want/need keyboard selection.

var mySelection = function (element) {
let startPos = element.selectionStart;
let endPos = element.selectionEnd;
let selectedText = element.value.substring(startPos, endPos);

if(selectedText.length <= 0) {
return; // stop here if selection length is <= 0
}

// log the selection
console.log("startPos: " + startPos, " | endPos: " + endPos );
console.log("selectedText: " + selectedText);

};

var textAreaElements = document.querySelectorAll('textarea');
[...textAreaElements].forEach(function(element) {
// register "mouseup" event for the mouse
element.addEventListener('mouseup', function(){
mySelection(element)
});

// register "keyup" event for the keyboard
element.addEventListener('keyup', function( event ) {
// assuming we need CTRL, SHIFT or CMD key to select text
// only listen for those keyup events
if(event.keyCode == 16 || event.keyCode == 17 || event.metaKey) {
mySelection(element)
}
});
});
textarea {
resize: none;
width: 50%;
height: 50px;
margin: 1rem auto;
}
<textarea>I am a student and I want to become a good person</textarea>

How to get the selected text position in a html contenteditable div tag?

Get Selected Position

You can retrieve the selected position of a contenteditable div using the document's range observer. The API is slightly different from a texture element. Note: A similar (perhaps better) solution can be found here (credit: Tim Down).

// Step 1: Retrieve elementslet textarea = document.querySelectorAll('.textarea');
// Step 2: Bind eventstextarea.forEach(txt=>{ txt.addEventListener('mouseup', eventHandler) txt.addEventListener('keyup', eventHandler)})function eventHandler(e){ getPosition(e.target) }

// Step 3: Determine cursor positionsfunction getPosition(el){ let position = {start:0,end:0}; let selection = document.getSelection(); if (el.matches('textarea')){ let offset = 1 position.start = el.selectionStart + offset position.end = el.selectionEnd + offset } else { if (selection.rangeCount){ let range = selection.getRangeAt(0); let range2 = range.cloneRange() // don't mess with visible cursor range2.selectNodeContents(el) // select content position.start = range.startOffset position.end = range.endOffset } } console.log(position.start, position.end)}
<textarea class="textarea">I am on</textarea>
<div class="textarea" contenteditable="true"> <p> I am on </p></div>

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);
}
};
})();

Position of selection in javascript

You almost got it right!

Its the startOffset which is causing it not to work.

Currently it is:

var startOffset = preCaretRange.toString().length;

The value on the RHS which is preCaretRange.toString().length is going to return you the total length of the string which has been selected, and not the start position. To get the start position you would use the startOffset property stored by the range. Therefore:

var startOffset = preCaretRange.startOffset;

A note on optimization: you do not need to clone range into preCaretRange..

document.body.addEventListener('mouseup', function () {
if (typeof window.getSelection != 'undefined') {
var sel = window.getSelection();
var range = sel.getRangeAt(0);

var startOffset = range.startOffset;
var endOffset = startOffset + range.toString().length - 1;

console.log("Selection starts at: " + startOffset);
console.log("Selection ends at: " + endOffset);
}
}, false);

Here is a fiddle which demonstrates it working with an actual text selection: http://jsfiddle.net/Dp3qp/3/



Related Topics



Leave a reply



Submit