Координаты выделенной области
Существует ли у DOM какая нибудь уловка, чтобы определить offsetTop и offsetLeft через range или getSelection? Проще говоря, на странице есть выделенная область, как получить её координаты?
|
Как оказалось, задачка достаточно просто решается, однако информации по инету я никакой не нашёл. А решение её следующее.
Допустим что у нас есть некоторый range в котором известны начальный и конечный контейнеры, а так же оффсеты начальной и конечной точки
//устанавливаем начальную точку
range.setStart(startContainer,startOffset);
//сворачиваем выделение в каретку и перемещаем её в начальную точку range
range.collapse(true);
//создаем временный элемент по которому будем определять координаты стартовой точки range
var tmp=document.createElement('b');
tmp.innerHTML='|';
//вставляем полученый элемент в начало range
range.insertNode(tmp);
//получаем координаты
var xy=getCoordXY(tmp);
alert('Left: '+xy.x+"px;\nTop: "+xy.y+'px;');
//больше нам tmp не нужен
removeEl(tmp);
/**
* На этом можно было и завершить
* Однако после insertNode(), startContainer был разделён на 2 элемента
* Поэтому, если дальше есть действие выделения участка текста программно
* код прервется ошибкой, так как содержимое startContainer было изменено
* Поэтому требуется "вернуть всё в зад"
*/
//отделёный элемент от startContainer это startContainer.nextSibling
//от него требуется получить содержимое и конкатенировать с содержимым startContainer
startContainer.nodeValue+=startContainer.nextSibling.nodeValue;
//nextSibling теперь нам то же не нужен
removeEl(startContainer.nextSibling);
//создаем выделение на странице
range.setStart(startContainer,starOffset);
range.setEnd(endContainer,endOffset);
s.removeAllRanges();
s.addRange(range);
//All Done!
Ну и дополнительные функции для этого решения
Number.prototype.NaN0=function(){return isNaN(this)?0:this;}
function getCoordXY(obj){
var left=0;
while(obj.offsetParent){
left+=obj.offsetLeft+(obj.currentStyle?(parseInt(obj.currentStyle.borderLeftWidth)).NaN0():0);
obj=obj.offsetParent;
}
left+=obj.offsetLeft+(obj.currentStyle?(parseInt(obj.currentStyle.borderLeftWidth)).NaN0():0);
var top=0;
while(obj.offsetParent){
top+=obj.offsetTop+(obj.currentStyle?(parseInt(obj.currentStyle.borderTopWidth)).NaN0():0);
obj=obj.offsetParent;
}
top+=obj.offsetTop+(obj.currentStyle?(parseInt(obj.currentStyle.borderTopWidth)).NaN0():0);
return {x:left,y:top};
}
function removeEl(){
if(obj.parentNode)
obj.parentNode.removeChild(obj);
else
delete obj;
}
|
left+=obj.offsetLeft+(obj.currentStyle?(parseInt(obj.currentStyle.borderLeftWidth)).NaN0():0); а зачем добавлять border, тем более в ie? можно написать obj.currentStyle && parseInt(obj.currentStyle.borderLeftWidth) || 0 вместо obj.currentStyle?(parseInt(obj.currentStyle.border TopWidth)).NaN0():0 |
Цитата:
Цитата:
|
у меня с border'ом были проблемы в ff. Смотрим mootools:
getOffsets: function(){
if (Browser.Engine.trident){
var bound = this.getBoundingClientRect(), html = this.getDocument().documentElement;
var isFixed = styleString(this, 'position') == 'fixed';
return {
x: bound.left + ((isFixed) ? 0 : html.scrollLeft) - html.clientLeft,
y: bound.top + ((isFixed) ? 0 : html.scrollTop) - html.clientTop
};
}
var element = this, position = {x: 0, y: 0};
if (isBody(this)) return position;
while (element && !isBody(element)){
position.x += element.offsetLeft;
position.y += element.offsetTop;
if (Browser.Engine.gecko){
if (!borderBox(element)){
position.x += leftBorder(element);
position.y += topBorder(element);
}
var parent = element.parentNode;
if (parent && styleString(parent, 'overflow') != 'visible'){
position.x += leftBorder(parent);
position.y += topBorder(parent);
}
} else if (element != this && Browser.Engine.webkit){
position.x += leftBorder(element);
position.y += topBorder(element);
}
element = element.offsetParent;
}
if (Browser.Engine.gecko && !borderBox(this)){
position.x -= leftBorder(this);
position.y -= topBorder(this);
}
return position;
},
|
Цитата:
|
| Часовой пояс GMT +3, время: 22:59. |