JSFiddle - React, Tailwind, and code Playground
HTML
<div class="container"><span>Septimus: </span><span>No </span><span>more </span><span>you </span><span>can, </span><span>time </span><span>must </span><span>needs </span><span>run </span><span>backward, </span><span>and </span><span>since </span><span>it </span><span>will </span><span>not, </span><span>we </span><span>must </span><span>stir </span><span>our </span><span>way </span><span>onward </span><span>mixing </span><span>as </span><span>we </span><span>go, </span><span>disorder </span><span>out </span><span>of </span><span>disorder </span><span>into </span><span>disorder </span><span>until </span><span>pink </span><span>is </span><span>complete, </span><span>unchanging </span><span>and </span><span>unchangeable, </span><span>and </span><span>we </span><span>are </span><span>done </span><span>with </span><span>it </span><span>for </span><span>ever. </span><span>(Thomisina </span><span>is </span><span>in </span><span>rapt </span><span>attention, </span><span>as </span><span>Septimus </span><span>stops </span><span>himself.) </span><span>This </span><span>is </span><span>known </span><span>as </span><span>free </span><span>will </span><span>or </span><span>self-determination.</span></div>
<textarea id="selector" rows="20" cols="50"></textarea>
CSS
.container {
width: 200px;
min-height: 200px;
background: #eee;
}
.selected {
background: rgba(60,120,180,0.3);
}
JavaScript
(function()
{
var a = false,
b = false,
words = $('.container span'),
positions = [],
temp;
// go through words
for( var i = 0; i < words.length; i++ )
{
temp = $(words[i]);
positions[i] = temp.offset();
positions[i].right = positions[i].left + temp.width();
positions[i].bottom = positions[i].top + temp.height();
positions[i].i = i;
positions[i].el = words[i];
}
$(window).mousedown(function(e)
{
a = match({left:e.pageX, top:e.pageY});
return false;
});
$(window).mouseup(function(e)
{
var temp, i;
$('.selected').removeClass('selected');
b = match({left:e.pageX, top:e.pageY});
if( a && b )
{
if( a > b )
{
temp = a;
a = b;
b = temp;
}
var text = [];
for( i = a.i; i <= b.i; i++ )
{
text.push($(positions[i].el).addClass('selected').text());
}
$('#selector').val(text.join('')).select();
}
else
{
$('#selector').val('');
}
});
function match(pos)
{
var i;
for( i = 0; i < positions.length; i++ )
{
if( in_box(pos, positions[i]) )
{
return positions[i];
}
}
}
function in_box(pos, box)
{
return (
pos.left >= box.left
&& pos.left <= box.right
&& pos.top >= box.top
&& pos.top <= box.bottom
);
}
})();