I have text in a tag:
Hello world... and goodbye mind A B!
How do I increase the area in which the te
Here is one approach that can be considered if you are ok to have some extra clicks
Here is my attempt: https://jsfiddle.net/vnathalye/rtw5bvLx/6/
$('.expandable').click(function(e){
var clicked = findClickedWord(e.target.childNodes[0], e.clientX, e.clientY);
if(clicked){
var $expanded = $('')
.appendTo('body')
.addClass('expanded')
.css({
position: "absolute",
left: clicked[3].left,
top: clicked[3].top,
//width: "100px",
//height: "100px"
})
.append($("").text(clicked[0]));
var data = {originalElem: e.target.childNodes[0], index: clicked[1], starts: clicked[2]};
$expanded.data("parentData", data);
$expanded.on('mouseup', selectionChanged);
$expanded.on('touchend touchcancel', selectionChanged);
//alert(JSON.stringify(clicked));
}
});
function selectionChanged(e){
try {
var $expanded = $(e.target);
var data = $expanded.parents(".expanded").data("parentData");
var selection = window.getSelection();
if(selection.rangeCount){
var range1 = selection.getRangeAt(0);
//alert(range1.startOffset + ":" + range1.endOffset);
var range2 = document.createRange();
var originalOffset = data.index>0? data.starts[data.index-1] : data.starts[0];
range2.setStart(data.originalElem, originalOffset + range1.startOffset);
range2.setEnd(data.originalElem, originalOffset + range1.endOffset);
selection.removeAllRanges();
selection.addRange(range2);
}
} catch(err){
alert(err);
}
$expanded.parents(".expanded").remove();
}
function findClickedWord(parentElt, x, y) {
if (parentElt.nodeName !== '#text') {
console.log('didn\'t click on text node');
return null;
}
var range = document.createRange();
var words = parentElt.textContent.split(' ');
var start = 0;
var end = 0;
var starts=[];
var ends=[];
for (var i = 0; i < words.length; i++) {
var word = words[i];
end = start+word.length;
starts.push(start);
ends.push(end);
range.setStart(parentElt, start);
range.setEnd(parentElt, end);
// not getBoundingClientRect as word could wrap
var rects = range.getClientRects();
var clickedRect = isClickInRects(rects);
if (clickedRect) {
var str = (i==0)? word : words[i-1] + " " + word;
if(i!=words.length-1) str += " " + words[i+1];
return [str, i, starts, clickedRect];
}
start = end + 1;
}
function isClickInRects(rects) {
for (var i = 0; i < rects.length; ++i) {
var r = rects[i]
if (r.leftx && r.topy)
{
return r;
}
}
return false;
}
return null;
}
Note:
Credits
Let me know your thoughts