Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Несколько вопросов по execCommand (https://javascript.ru/forum/misc/4951-neskolko-voprosov-po-execcommand.html)

ExtendedPlay 01.09.2009 18:31

Несколько вопросов по execCommand
 
Привет всем!
Пишу WYSIWYG-редактор. Он почти готов, осталось только разобраться с несколькими не слишком важными, но очень напрягающими моментами.

[Есть ответ] Задача 1. При нажатии Enter, ФаерФокс вставляет <br>, а ИЕ - <p>.
Мне нужно чтобы они оба работали через <br>.


Задача 2. При вставке с помощью pasteHTML, содержимое вставляется после мигающего курсора.
Нужно чтобы содержимое появлялось до курсора, либо чтобы курсор сам отодвигался на нужное количество символов.

[Есть ответ] Задача 3. При вставке ссылки с помощью createLink, если текст для будущей ссылки не выделен, ИЕ вставляет текст ссылки, а ФФ не вставляет ничего.

Пожалуйста, помогите решить эти три задачки)

Заранее благодарю откликнувшихся!

Octane 01.09.2009 18:57

Это все не тривиально, в одну или две строчки решения не получится, придется много работать с DOM и объектами Range/TextRange, возможно даже без использования execCommand.

ExtendedPlay 01.09.2009 19:47

что ж, с помощью Range/TextRange решил 3-ю задачу. точнее смог проверить, выделен ли текст. спасибо Octane.
осталось еще 2)

Цитата:

Это все не тривиально, в одну или две строчки решения не получится, придется много работать с DOM и объектами
да, это понятно, хотя второй вопрос думаю несложно решить, только я совершенно не представляю как это сделать)
а вот первый вопрос самый сложный (как мне кажется). вот на него как раз и хотелось бы узнать ответ больше всего)

Octane 01.09.2009 19:57

По первому пункту нажатие Enter внутри списка списка надо отфильтровывать. И простой заменой абзаца на <br> не обойтись, проблем больше. Например, при удалении форматирования списков, все элементы помещаются в <p> или разделяются через <br>. Причем абзацы добавляет еще и Opera, поэтому количество кода удвоится, так как задачу придется решать W3C-методами объекта Range для Opera и TextRange – для IE.
Отлавливайте нажатие этой кнопки и заменяйте на <br> параграфы, получая их с помощью все тех же Range/TextRange.

А еще в WebKit есть баг, когда после искуственно вставленного <br /> больше нет символов, то переход на новую строку не будет осуществлен, нужно вставлять еще один <br /> или любой символ.

Вообще лучше использовать абзацы, а от <br /> вообще избавиться. Например, в MS Word нажатие Enter всегда приводит к образованию нового абзаца, никаких разрывов строк нет.

Статья по теме: Range, TextRange и Selection

ExtendedPlay 01.09.2009 20:17

Цитата:

Статья по теме: Range, TextRange и Selection
читал, спасибо)

Цитата:

Вообще лучше использовать абзацы, а от <br /> вообще избавиться. Например, в MS Word нажатие Enter всегда приводит к образованию нового абзаца, никаких разрывов строк нет.
ну а причем тут МСВорд? так и не ясно почему лучше <p>)

ну да ладно... будем использовать <p>. это я сделал без проблем.

что ж, остался лишь один вопрос: как заставить pasteHTML вставлять текст перед курсором (или как сдвигать курсор в конец вставки)?
опять Range/TextRange? xD

Octane 01.09.2009 20:23

Цитата:

Сообщение от ExtendedPlay
ну а причем тут МСВорд? так и не ясно почему лучше <p>)

MS Word тоже WYSIWYG-редактор, причем самый распространенный, поэтому именно его поведение удобнее скопировать для пользователей.
А <p> луше использовать, хотя бы потому, что его IE лепит везде, а средствами TextRange не особо удобно переделывать все на <br />. Ну и текст верстают обычно абзацами ;)


Цитата:

Сообщение от ExtendedPlay
что ж, остался лишь один вопрос: как заставить pasteHTML вставлять текст перед курсором (или как сдвигать курсор в конец вставки)?

Что вы вставляете через pasteHTML, просто текст?

ExtendedPlay 01.09.2009 20:24

Цитата:

Что вы вставляете через pasteHTML?
просто текст без форматирования.

Octane 01.09.2009 20:31

ну можно, например, сделать копию (duplicate) объекта TextRange, полученного до вставки текста. Затем восстановить его (select) и схлопнуть (collapse) выделение в каретку (курсор).

ExtendedPlay 01.09.2009 21:09

хм... интересный способ... но вот только если совпадений будет несколько, он не сработает (вроде бы).
просто с помощью pasteHTML я вставляю смайлы типа :-) и :wink:
смайлов может быть много... причем одинаковых)))))))))

Octane 01.09.2009 21:28

Почему не сработает? В дубликате TextRange останутся старые границы, которые в нужном месте и будут восстановлены, если конечно pasteHTML не заменит выделенный участок. Метод findText не используем же.

Можно конечно и самостоятельно границы выделения сдвинуть:
textrange.moveStart("character", количество_символов);
textrange.moveEnd("character", количество_символов);

или чтобы не двигать конечную точку, сделать textrange.collapse(true)

Главное не забыть потом восстановить визуальное выделение методом select.


Часовой пояс GMT +3, время: 20:44.