Товарищи хочу поделиться опытом решения следующей задачи: "Необходимо получить координаты курсора находящегося в текстовом поле в пикселях".
Собственно сложность заключается как раз в том как вычислить положение курсора в пикселях. Получить положение курсора в символах (т.е. индекс символа перед которым стоит курсор) достаточно просто. Но универсального кроссбраузерного способа получить положение курсора в пикселях, который работал бы со всеми ньюансами расположения его (курсора) в текстовом поле и для всех видов текстовых полей (input, textarea) не существует!
Далее привожу основные идеи которые необходимо реализовать для решения задач подобных этой. Сразу оговорюсь, что стартовой точкой для моего исследования стала библиотека vegUI (
http://vegui.org), и метод vsk_frm_cursor_offset (
http://vskdoc.vegui.org/files/vegui-...mtools-js.html) этой библиотеки :
1) В IE все относительно просто. Объект selection предоставляет методы получения положения курсора относительно текстового поля(!) в котором находится курсор. (подробнее об объекте selection здесь
http://habrahabr.ru/blogs/javascript/55922/)
Вот пример получения x координаты курсора в однострочном текстовом поле (input):
var r = document.selection.createRange();
return r.offsetLeft;
Этот код вернет x-координату начала выделенного текста в текстовом поле, в случае если текст не выделен, то начало и конец выделенной области совпадают и представляют из себя положение в которое в данный момент установлен курсор.
2) Для того что бы вычислить положение в других браузерах необходимо создать невидимый элемент div с теми же стилями влияющими на размер букв текста и смещения текста внутри поля (т.е. все font, padding, border стили) скопировать туда все содержимое текстового поля. После символа за которым расположен курсор в текстовом поле вставить какой-либо inline элемент HTML, и получить его смещения относительно родительского div элемента. Эти смещения и будут искомыми координатами.
Здесь есть одно но в том числе из-за которого функция vsk_frm_cursor_offset не сработала для меня. Если требуется узнать положение курсора в однострочном текстовом поле (input элемент) и при этом содержимое поля достаточно длинное, т.е. не умещается в поле по ширине, то если необходимо вычислить положение после того как пользователь прокрутил содержимое поля вправо, необходимо учесть смещение на которое пользователь прокрутил содержимое. В объектной модели DOM браузера Fire Fox (у меня версия 3.5.7) и возможно дугих Gecko браузеров нет универсальной возможности получить данное смещение. Поэтому вот два обходных пути которые можно реализовать в данном случае:
- использовать вместо элемента input элемент textarea. При этом потребуется перехватывать события JavaScript'ом и запрещать реакцию по умолчанию на них, например нажатие Enter (так же необходимо подумать о вставке из буфера обмена), если необходимо что бы поле оставалось однострочным. В этом случае свойство scrollLeft вернет требуемое нам смещение в пикселях. В случае многострочного поля scrollTop возвращает смещение по вертикали.
- использовать элемент input. Но при этом, т.к. scrollLeft для input элементов всегда равен 0, придется определять требуемое нам смещение "обходными путями", которые могут иногда не работать, а именно если вы собираетесь программно изменять содержимое текстового поля и позиционировать курсор, то из-за проблемы описанной в этой ветке форума http://javascript.ru/forum/css-html-firefox-mizilla/7615-prokrutit-tekst-do-nuzhnojj-pozicii-v-text-box'e.html следующий подход может не сработать - подумайте об textarea в этом случае. Что бы определить требуемое нам смещение придется создать невидимое поле textarea такой же ширины, с теми же стилями текста и стилями влияющими на отступы текста от границ поля. Скопировать туда содержимое текстового поля, затем спозиционировать курсор и принудительно прокрутить поле до курсора, как это описано в упомянутой выше ветке (http://javascript.ru/forum/css-html-firefox-mizilla/7615-prokrutit-tekst-do-nuzhnojj-pozicii-v-text-box'e.html). После чего свойство scrollLeft будет содержать требуемое нам смещение.
Пожалуйста комментируйте, критикуйте предлагайте более оптимальные решения. Любые комментарии приветствуются!
PS. Надеюсь комму-нибудь этот пост будет полезен или сэкономит время, у меня ушло 3 дня на исследование и реализацию.