I have the following working code: http://jsfiddle.net/henrichro/Z75wS/
When the user is selecting some text, left and right markers will appear, just like on iPhones for example. Selection is possible also backwards. The code was mainly built on the solution found here https://stackoverflow.com/a/15369695/621639 , of course changed a little bit, converted the jQuery into JS, as my main goal is to write everything in JavaScript, instead of using any library.
What I need, is to make the markers draggable, so I can extend or shrink the selection.
Current JavaScript code:
function applySelectionMarkers() {
if( !window.getSelection().isCollapsed ) {
var sel = window.getSelection();
var range = document.createRange();
range.setStart( sel.anchorNode, sel.anchorOffset );
range.setEnd( sel.focusNode, sel.focusOffset );
var backwards = range.collapsed;
range.detach();
var rects = sel.getRangeAt(0).getClientRects();
var n = rects.length - 1;
//console.log(rects);
var lineHeight = getLineHeight( edit );
var markerRight = document.getElementById( "markerRight" );
var markerRightWidth = markerRight.offsetWidth;
var markerLeft = document.getElementById( "markerLeft" );
var markerLeftWidth = markerLeft.offsetWidth;
if ( markerRightWidth == 0 ) {
markerRightWidth = 10;
}
if ( markerLeftWidth == 0 ) {
markerLeftWidth = 10;
}
if ( lastCharRTL( getSelectionHtml() ) ) {
markerLeft.style.top = ( rects[0].top + lineHeight ) + "px";
markerLeft.style.left = ( rects[0].left - markerLeftWidth ) + "px";
markerLeft.style.display = "block";
markerRight.style.top = ( rects[n].top + lineHeight ) + "px";
markerRight.style.left = ( rects[n].left - markerRightWidth ) + "px";
markerRight.style.display = "block";
//alert( "one" + markerLeftWidth );
} else if ( backwards ) {
markerLeft.style.top = ( rects[n].top + lineHeight ) + "px";
markerLeft.style.left = rects[n].right + "px";
markerLeft.style.display = "block";
markerRight.style.top = ( rects[0].top + lineHeight ) + "px";
markerRight.style.left = ( rects[0].left - markerRightWidth ) + "px";
markerRight.style.display = "block";
//alert( "two" + markerRightWidth );
} else {
markerLeft.style.top = ( rects[0].top + lineHeight ) + "px";
markerLeft.style.left = ( rects[0].left - markerLeftWidth ) + "px";
markerLeft.style.display = "block";
markerRight.style.top = ( rects[n].top + lineHeight ) + "px";
markerRight.style.left = rects[n].right + "px";
markerRight.style.display = "block";
//alert( "three" + markerLeftWidth );
}
} else {
markerLeft.style.display = "none";
markerRight.style.display = "none";
}
}
function getSelectionHtml() {
var html = "";
if ( typeof window.getSelection != "undefined" ) {
var sel = window.getSelection();
if ( sel.rangeCount ) {
var container = document.createElement( "div" );
for ( var i = 0, len = sel.rangeCount; i < len; ++i ) {
container.appendChild( sel.getRangeAt(i).cloneContents() );
}
html = container.innerHTML;
}
} else if ( typeof document.selection != "undefined" ) {
if ( document.selection.type == "Text" ) {
html = document.selection.createRange().htmlText;
}
}
return html;
}
function lastCharRTL( txt ) {
return /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]$/.test(txt);
}
// line height in selectie ca putem adauga la markerLeft top attribute
function getLineHeight( element ){
var temp = document.createElement( element.nodeName );
temp.setAttribute( "style","margin:0px;padding:0px;font-family:"+element.style.fontFamily+";font-size:"+element.style.fontSize );
temp.innerHTML = "test";
temp = element.parentNode.appendChild( temp );
var ret = temp.clientHeight;
temp.parentNode.removeChild( temp );
return ret;
}
document.onmouseup = function() {
applySelectionMarkers();
}
function KeyPress(e) {
var evtobj = window.event ? event : e;
if ( evtobj.keyCode == 65 && evtobj.ctrlKey ) {
console.log(evtobj.keyCode);
applySelectionMarkers();
}
}
document.onkeydown = KeyPress;
Further credits:
https://stackoverflow.com/a/5222955/621639, https://stackoverflow.com/a/4515470/621639
Update: Playing while dragging one of the markers:
window.onload = function() {
draggable( 'markerLeft' );
}
var dragObj = null;
function draggable( id ) {
var obj = document.getElementById( id );
obj.style.position = "absolute";
obj.onmousedown = function() {
dragObj = obj;
}
}
document.onmouseup = function(e) {
dragObj = null;
}
document.onmousemove = function(e) {
var x = e.pageX;
var y = e.pageY;
if( dragObj == null )
return;
dragObj.style.left = x + "px";
dragObj.style.top = y + "px";
}
But when I drag the left marker (red), the whole selection disappears.