boundingclientrect of range
by sangelee
HTML
<p id='test'>click the <a href='javascript:;'>sample words</a> here</p>
<pre id='result'></pre>
<p class='tips'>
click the "sample" or "words" above,and the corresponding range will be lighlighted.The word "sample" not work properly.
</p>
<div id='client-rect'></div>
CSS
#result {
border:1px dashed green;
}
.tips {
color:brown;
}
#client-rect {
position:absolute;
background-color:rgba(255,0,0,0.5);
pointer-events:none;
}
JavaScript
var getRangeAtPoint = function(elem, x, y) {
if (elem.nodeType == elem.TEXT_NODE) {
var range = elem.ownerDocument.createRange();
range.selectNodeContents(elem);
var currentPos = 0;
var endPos = range.endOffset;
while (currentPos + 1 < endPos) {
range.setStart(elem, currentPos);
range.setEnd(elem, currentPos + 1);
var range_rect = range.getBoundingClientRect();
if (range_rect.left <= x && range_rect.right >= x &&
range_rect.top <= y && range_rect.bottom >= y) {
range.expand("word");
return range;
}
currentPos += 1;
}
} else {
for (var i = 0; i < elem.childNodes.length; i++) {
var range = elem.childNodes[i].ownerDocument.createRange();
range.selectNodeContents(elem.childNodes[i]);
var range_rect = range.getBoundingClientRect();
if (range_rect.left <= x && range_rect.right >= x &&
range_rect.top <= y && range_rect.bottom >= y) {
range.detach();
var computed_range = getRangeAtPoint(elem.childNodes[i], x, y);
if(computed_range){
return computed_range;
}
} else {
range.detach();
}
}
}
return (null);
};
document.querySelector('#test').addEventListener('mousedown',function(e){
var page_x = e.pageX - document.body.scrollLeft;
var page_y = e.pageY - document.body.scrollTop;
var target_ele = e.target;
var range = getRangeAtPoint(target_ele,page_x,page_y);
var rect = range.getBoundingClientRect();
document.querySelector('#result').innerText = JSON.stringify(rect,null,4);
//highlight the range
var clientRectDiv = document.querySelector('#client-rect');
clientRectDiv.style.width = rect.width+'px';
clientRectDiv.style.height = rect.height+'px';
...