I am building a WYSIWYG rich text editor.
When the user selects a portion of his/her text, I would like to present a menu in a tooltip. Presenting the menu works fine but I would like to only show it if the user hovers over the selected text.
As Illustrated:
I also haven't decided on positioning (I like the way that it's illustrated) but to clarify, that's not the point of the question.
The question is: How do I filter for a hover event that happens over selected text?
The Problems:
I can't just listen for a text selection event or test hover events to see whether they are over elements that have selected text inside them. The left image would generate a false positive with that.
I know how to get the selected text but I don't know how to get the selected region.
To my mind, the ideal solution is somehow to calculate the region of the selected text and test whether mouseover events happen in that region.
I am building a WYSIWYG rich text editor.
When the user selects a portion of his/her text, I would like to present a menu in a tooltip. Presenting the menu works fine but I would like to only show it if the user hovers over the selected text.
As Illustrated:
I also haven't decided on positioning (I like the way that it's illustrated) but to clarify, that's not the point of the question.
The question is: How do I filter for a hover event that happens over selected text?
The Problems:
I can't just listen for a text selection event or test hover events to see whether they are over elements that have selected text inside them. The left image would generate a false positive with that.
I know how to get the selected text but I don't know how to get the selected region.
To my mind, the ideal solution is somehow to calculate the region of the selected text and test whether mouseover events happen in that region.
Share Improve this question edited Jun 2, 2015 at 15:35 jcuenod asked Jun 2, 2015 at 14:56 jcuenodjcuenod 58.5k15 gold badges69 silver badges103 bronze badges 6- stackoverflow./questions/5379120/… Does this help? – ggzone Commented Jun 2, 2015 at 15:03
- That only gets the selected text: I actually need some way to get the region on the screen that the browser has drawn on. – jcuenod Commented Jun 2, 2015 at 15:05
- 1 May be you could wrap the selected text in a tag and bind hover to that specific tag? – lshettyl Commented Jun 2, 2015 at 15:13
- @LShetty not a bad idea, I was hoping for a more elegant solution. That will probably mean artificially reselecting the text and may run into problems when the selection is modified with the keyboard. Not sure, would have to experiment. – jcuenod Commented Jun 2, 2015 at 15:20
-
@LShetty also problems arise when part of the selection is over styled text - the html bees invalid
<b>hello <span>world</b> lorem</span>
– jcuenod Commented Jun 2, 2015 at 15:23
2 Answers
Reset to default 6On mouseup
, use Range.getClientRects to grab the bounding rectangles of each line of the selection.
You can then test if the mouse is over the selection like this:
var cr= [];
$(document).on({
'mouseup': function() {
cr= window.getSelection().getRangeAt(0).getClientRects();
},
'mousemove': function(ev) {
//hide the pop up
for(var i = 0 ; i < cr.length ; i++) {
if(ev.pageX >= cr[i].left && ev.pageX <= cr[i].right &&
ev.pageY >= cr[i].top && ev.pageY <= cr[i].bottom
) {
//show the pop up
break;
}
}
}
});
Fiddle
Try this way:
JS
$(document).ready(function () {
$(document).on("mouseup", ".conttext", function () {
var highlight = window.getSelection();
console.log(highlight);
var spn = '<span class="highlight">' + highlight + '</span>';
var text = $('.conttext').text();
$('.conttext').html(text.replace(highlight, spn));
});
$(document).on("mouseover", ".highlight", function () {
alert("You hovered on selected tex"); // Your tooltip code goes here
})
});
CSS:
.highlight {
color:#888;
position:relative;/*This will not matter if you inject tooltip using JS*/
display:inline-block;/*This will not matter if you inject tooltip using JS*/
}
HTML:
<div class="conttext">Sample text</div>
Demo: http://jsfiddle/lotusgodkk/BGKSN/202/