Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.07.2009, 19:28
Аспирант
Отправить личное сообщение для Pattern Посмотреть профиль Найти все сообщения от Pattern
 
Регистрация: 13.05.2009
Сообщений: 37

Координаты выделенной области
Существует ли у DOM какая нибудь уловка, чтобы определить offsetTop и offsetLeft через range или getSelection? Проще говоря, на странице есть выделенная область, как получить её координаты?
Ответить с цитированием
  #2 (permalink)  
Старый 17.07.2009, 16:20
Аспирант
Отправить личное сообщение для Pattern Посмотреть профиль Найти все сообщения от Pattern
 
Регистрация: 13.05.2009
Сообщений: 37

Как оказалось, задачка достаточно просто решается, однако информации по инету я никакой не нашёл. А решение её следующее.
Допустим что у нас есть некоторый 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;
}
Ответить с цитированием
  #3 (permalink)  
Старый 18.07.2009, 01:23
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

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

Последний раз редактировалось x-yuri, 18.07.2009 в 01:26.
Ответить с цитированием
  #4 (permalink)  
Старый 18.07.2009, 13:09
Аспирант
Отправить личное сообщение для Pattern Посмотреть профиль Найти все сообщения от Pattern
 
Регистрация: 13.05.2009
Сообщений: 37

Сообщение от x-yuri Посмотреть сообщение
а зачем добавлять border, тем более в ie?
Честно говоря уже не помню точно почему, так как функцию определения координат использую достаточно давно, какой то косяк с IE был, сейчас вспоминать и снова всё парсить не очень охото.
Сообщение от x-yuri Посмотреть сообщение
можно написать
obj.currentStyle && parseInt(obj.currentStyle.borderLeftWidth) || 0
вместо
obj.currentStyle?(parseInt(obj.currentStyle.border TopWidth)).NaN0():0
А за это спасибо, учту в будущем.
Ответить с цитированием
  #5 (permalink)  
Старый 18.07.2009, 13:35
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

у меня с 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;
    },
Ответить с цитированием
  #6 (permalink)  
Старый 18.07.2009, 14:02
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от x-yuri
Смотрим mootools:
В FF2 тоже проблемы.
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как получить координаты jeel Общие вопросы Javascript 3 07.07.2009 07:00
Получить координаты мыши alekciy Events/DOM/Window 2 28.12.2008 00:07
Определить координаты объекта в таблице ner2000 Events/DOM/Window 2 14.06.2008 01:56
Координаты snake-as Общие вопросы Javascript 1 04.03.2008 12:30
Координаты точки snake-as Общие вопросы Javascript 1 04.03.2008 12:23