Является ли конкретная координата X-Y между строк текста? - PullRequest
1 голос
/ 22 ноября 2011

Как можно определить, используя Javascript (jQuery будет работать), если определенная координата XY на странице HTML находится вертикально между двумя строками текста?Строки могут быть в середине длинного абзаца, внутри длинного тэга элемента строки, в промежутке, между двумя тэгами и т. Д. У меня нет способа контролировать точку HTML или XY, но мне нужно знать,Точка XY находится в середине строки текста, или если она находится между двумя строками текста;и это должно быть довольно эффективно.

Пожалуйста, задавайте любые вопросы, которые могут у вас возникнуть, если я не достаточно ясно.

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 22 ноября 2011

Имея дело с текстовыми диапазонами, я не думаю, что вы технически можете поместить что-либо «между» двумя строками текста в одном узле HTML.Даже если вы используете высоту строки, каждый пиксель принадлежит одной из линий (даже если между ними находится визуально пространство).

Я опущу несколько вариантов, которые могут помочь.

Простейший ответ, вероятно, состоит в том, чтобы просто использовать высоту строки: получить элемент dom, по которому щелкнули (event.relatedTarget в jQuery?), определить его смещение относительно страницы (то есть, где находится верх этого элемента), определить точку, по которой щелкнули (x, y координаты события мыши) сравните два, используя высоту строки текста в строке

Это будет выглядеть примерно так:

function getLines(topOfElement, clickPoint, lineHeight) {
   return Math.floor( (clickPoint - topOfElement)/lineHeight );
}

var topOfElement = $(element).offset().top; //must be position: relative|absolute
var clickedPoint = event.clientY; //might be pageY?
var lineHeight = parseFloat($(element).css('line-height')); //probably need to set this in px using css or it might be null
var textHeight = parseInt($(element).css('font-size')); //probably need to set this in px using css or it might be null
var prevLineNumber = getLines(topOfElement, clickedPoint, lineHeight);

// the previous line ends (in theory) at the bottom of the text (textHeight)
// you might need to adjust this definition to your needs
var prevLineBottom = prevLineNumber*lineHeight+topOfElement+textHeight;

// the next line begins (in theory) at the top of its line
// you might need to adjust this definition to your needs
var nextLineTop = (prevLineNumber+1)+lineHeight;

if( clickedPoint >= nextLineTop ) {
   alert('clicked on row '+(prevLineNumber+1));
}
else if( clickedPoint <= prevLineBottom ) {
   alert('clicked on row '+prevLineNumber);
}
else {
   alert('clicked between rows '+prevLineNumber+' and '+(prevLineNumber+1));
}

Есливы хотите увидеть, произошел ли щелчок между двумя html-узлами, вы можете сделать это с помощью Rangy , а также с помощью некоторого необычного выбора и вычисления диапазона.

Вы можете использовать его для таких вещей, как определение точной длины текста до и после выделения.Это полезно, только если вы хотите увидеть, где в тексте они щелкнули.

function getTextAtClick() {
   var result = {nodeClicked: null, textBefore: '', textAfter: '', valid: false};

   //get a selection object (even though the selection is technically zero length)
   var sel = rangy.getSelection(); 

   //you would probably want to discard any selection not zero length (i.e actual selection of text instead of a click)
   // if not, you'd need to decide what it means to select across multiple dom nodes :(
   if( sel.toString().length > 0 ) { return result; }

   // get the point where the click occurred
   var range = sel.getRangeAt(0);
   result.valid = true;

   // determine text in our dom element up to the click point
   var before = rangy.createRange();
   before.setStart(range.startContainer, 0);
   before.setEnd(range.startContainer, range.startOffset);
   result.textBefore = before.toString();

   // determine text in our dom element after the click point
   var after = rangy.createRange();
   after.setStart(range.startContainer, range.startOffset+1);
   after.setEndAfter(range.startContainer);
   result.textAfter = after.toString();

   return result;
}
1 голос
/ 22 ноября 2011

Вы можете позвонить .getBoundingClientRect() в текстовом диапазоне.Вам нужно будет написать отдельный код для браузеров IE и не IE, чтобы получить текстовые диапазоны.

Это должно быть относительно легко в IE, благодаря textRange.moveToPoint(x, y).Для других браузеров вам нужно будет сделать что-то вроде бинарного поиска по элементам в DOM, вызывая .getBoundingClientRect() по элементам, пока вы не найдете элемент, содержащий ваш текст.Затем создайте диапазон, содержащий текст этого элемента, и выполните бинарный поиск по диапазону, чтобы определить, перекрывает ли ваша точка какой-либо текст.

Все это будет очень сложно, если вы располагаете абсолютно позиционированные элементы с перекрытием текстадругие элементы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...