Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
170
rated 0 times [  174] [ 4]  / answers: 1 / hits: 29476  / 15 Years ago, mon, october 19, 2009, 12:00:00

tl;dr


The idea is to allow a user to mark any text and see menu pop-up just next to the selection, with possible actions to apply to the selected text.




I need to position an absolute positioned button next to user's selected text.


I'm binding a mouseup event to the Document, and getting the selected text, but I'm currently out of ideas on how to know where the actual selection is positioned, without wrapping it in some element, because selection of text can be across several elements, and it would mess the structure if I would wrap it.


More From » dom

 Answers
30

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

[#98487] Wednesday, October 14, 2009, 15 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
longd

Total Points: 616
Total Questions: 110
Total Answers: 101

Location: Andorra
Member since Sat, May 27, 2023
1 Year ago
;