Комментарии 28
Ух, как здорово! Спасибо!
Вэлкам!
Размочим нулевое количество комментов :-)
Хотя, к справочным данным особо ничего в догонку не напишешь…
Размочим нулевое количество комментов :-)
Хотя, к справочным данным особо ничего в догонку не напишешь…
Ну можно начать ругать эксплорер за собственые реализации.
Тесты в stable-версии ИЕ8 показали, что ребята из Силиконовой долины перенесли реализацию TextRange в свой флагман. Так что статья будет еще долгое время актуальной.
DOM-реализации Range автор там не нашел. Может плохо искал?
DOM-реализации Range автор там не нашел. Может плохо искал?
Меду так прочим такой обьект появился вначале в ие а потом уже и у других браузеров только почемуто с совершенно другим интерфейсом.
В IE реализация работы с выделениями лучше.
Легко посчитать размеры в пикселях занятые под выделение.
Одинаковая логика работы с выделениями что внутри input-ах с textarea-ми, что вне их.
Единственный минус тот же что и в innerHTML — не работает правильно вставка содержимого внутри таблиц, списков и т.п. и возвращает творчески переосмысленный html код выделенного.
Легко посчитать размеры в пикселях занятые под выделение.
Одинаковая логика работы с выделениями что внутри input-ах с textarea-ми, что вне их.
Единственный минус тот же что и в innerHTML — не работает правильно вставка содержимого внутри таблиц, списков и т.п. и возвращает творчески переосмысленный html код выделенного.
Для решения каких задач вам нужно знать число пикселей под выделением? :-)
В целом, DOM-реализация Range мне нравится тем, что граничные точки теснее привязаны к DOM. Это удобнее, чем манипулировать текстовыми смещениями.
Хотя вопрос удобства той или иной реализации можно решить только на примере конкретных практических задач. Абстрактные рассуждения, имхо, не уместны.
В целом, DOM-реализация Range мне нравится тем, что граничные точки теснее привязаны к DOM. Это удобнее, чем манипулировать текстовыми смещениями.
Хотя вопрос удобства той или иной реализации можно решить только на примере конкретных практических задач. Абстрактные рассуждения, имхо, не уместны.
реальная задача, разбить длинное (в пикселях) слово, чоб не уползало за экран.
Это вам кажется что удобно, привязка текста к DOM элементам. Это две независящие друг от друга стихии… вот удалите вы DOM элемент в котором стартует выделение и что? придется сохраненный ранее бекап выделения придется переосмысливать.
Это вам кажется что удобно, привязка текста к DOM элементам. Это две независящие друг от друга стихии… вот удалите вы DOM элемент в котором стартует выделение и что? придется сохраненный ранее бекап выделения придется переосмысливать.
Задачу, которую вы привели в пример, не стоит решать через Range (если я конечно правильно понял суть):
fastcoder.org/articles/?aid=183
С удалением DOM-элементов, если этим занимается скрипт, а не пользователь, конечно, беда. Придется проверять не является ли элемент контейнером анкора/фокуса и переносить граничную точку в родительский узел. Из комментов ниже я понял, что в ИЕ для этого букмарки сделали.
fastcoder.org/articles/?aid=183
С удалением DOM-элементов, если этим занимается скрипт, а не пользователь, конечно, беда. Придется проверять не является ли элемент контейнером анкора/фокуса и переносить граничную точку в родительский узел. Из комментов ниже я понял, что в ИЕ для этого букмарки сделали.
Давно пора об этом было поговорить :)
Супер и материал и оформление!
Спасибо большое, очень давно интересовал этот вопрос, но руки не доходили разобраться. Было бы просто великолепно, если бы вы написали еще про создание простейшего wysiwyg редактора.
Странно, первый раз ушло мимо треда…
вот немного более полная статья на тему
dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-1/
dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-1/
может автор подскажет как при вызове таких функций как InsertUnorderedList (или к примеру функции зачистки html кода) сохранить выделение/положение курсора? перепробывал кучу всяких вариантов — ничего толкового…
Вероятно, вы имеете в виду команду «InsertUnorderedList» метода execCommand?
На вскидку, можно попробовать сохранять выделение(фокус) в виде Range(TextRange)-объекта, производить манипуляцию, а затем восстанавливать фокус из сохраненного объекта. Примерно так:
// Получим выделение (фокус)
var sel = window.getSelection? window.getSelection(): document.selection;
// Создадим из него Range(TextRange)-объект
var rng = window.getSelection? sel.getRangeAt(0): sel.createRange();
// На всякий случай сделаем клон
var rngClone = window.getSelection? rng.cloneRange(): rng.duplicate();
/*
Здесь выполним нужную команду метода execCommand
*/
// Восстановим фокус из клона
if ( window.getSelection ) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange( rngClone );
} else rngClone.select();
Набивал прямо здесь без проверки, так что возможны ошибки, да и код можно оптимизировать. Но направление мыслей должно быть понятным…
На вскидку, можно попробовать сохранять выделение(фокус) в виде Range(TextRange)-объекта, производить манипуляцию, а затем восстанавливать фокус из сохраненного объекта. Примерно так:
// Получим выделение (фокус)
var sel = window.getSelection? window.getSelection(): document.selection;
// Создадим из него Range(TextRange)-объект
var rng = window.getSelection? sel.getRangeAt(0): sel.createRange();
// На всякий случай сделаем клон
var rngClone = window.getSelection? rng.cloneRange(): rng.duplicate();
/*
Здесь выполним нужную команду метода execCommand
*/
// Восстановим фокус из клона
if ( window.getSelection ) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange( rngClone );
} else rngClone.select();
Набивал прямо здесь без проверки, так что возможны ошибки, да и код можно оптимизировать. Но направление мыслей должно быть понятным…
все бы хорошо, но в range сохраняется контейнер и смещение — которых после операции может попросту не быть, или смещение может быть уже совсем другим…
из того что я рыл в коде тини — они оставляют некие букмарки\якоря по которым потом востанавливают выделение — но как это сделано там я так и не смог осилить…
из того что я рыл в коде тини — они оставляют некие букмарки\якоря по которым потом востанавливают выделение — но как это сделано там я так и не смог осилить…
Если используемая вами команда занимается вставкой данных, то описанный выше скрипт должен справляться.
В контексте объекта TextRange можно вызвать метод getBookmark(), который вернет строку (там свой внутренний формат какой-то). Позже, скормив эту строку методу moveToBookmark(), вы можете восставновить фокус. Это, кстати, описано в статье. Работает в ИЕ соот-но.
Аналогичного интерфейса в DOM Range не встречал, используйте стандартные свойства и методы.
В контексте объекта TextRange можно вызвать метод getBookmark(), который вернет строку (там свой внутренний формат какой-то). Позже, скормив эту строку методу moveToBookmark(), вы можете восставновить фокус. Это, кстати, описано в статье. Работает в ИЕ соот-но.
Аналогичного интерфейса в DOM Range не встречал, используйте стандартные свойства и методы.
Коллективный разум существует? Вчера искал инфу по установке пользовательских выделений, но все на что натыкался в основном было про текст в инпутах. И вчера же появляется ваша статья здесь, в которой всё доходчиво изложено. Спасибо за труд.
Эту статью я начал писать в феврале, когда окончательно надоело собирать API по пяти разным ссылкам. Недавно дописал и выложил на fastcoder.org. Ну а потом подумалось, что материал будет полезен хабровчанам. Хорошо, что не ошибся :-)
НЛО прилетело и опубликовало эту надпись здесь
Хорошая статья, до сих пор к ней возвращаюсь (пишу визуальный редактор)
Автор, подскажите пожалуйста, как быть в моем случае?
Мне нужно получить текст только из одного узла. Т.е. если имеется div, внутри которого есть текст, то при выделении и нажатии на кнопку я хочу, чтобы выделение идентифицировалось только в случае если оно находится в этом div.
Вот так я получаю выделение ото всюду. Но ведь getSelection() — метод window, а следовательно его я не могу заменить его на свой узел.
var selection = window.getSelection().getRangeAt(0);
Буду благодарен за помощь.
Мне нужно получить текст только из одного узла. Т.е. если имеется div, внутри которого есть текст, то при выделении и нажатии на кнопку я хочу, чтобы выделение идентифицировалось только в случае если оно находится в этом div.
Вот так я получаю выделение ото всюду. Но ведь getSelection() — метод window, а следовательно его я не могу заменить его на свой узел.
var selection = window.getSelection().getRangeAt(0);
Буду благодарен за помощь.
Есть еще либа для таких нужд: code.google.com/p/rangy/
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Range, TextRange и Selection