26.08.2011, 21:08
|
Интересующийся
|
|
Регистрация: 05.08.2010
Сообщений: 24
|
|
IE - editor - потеря focus-а
Самописный редактор (iframe), редактируем текст, курсор мигает в нутри текста, жмем кнопку вставки ссылки - открывается новое окно или плавающий div внутри с фреймом, нажимаем вставить ссылку.
Так вот, если новое окно - ссылка вставится в последнее место курсора, а если плавающий див - места курсора теряется ... принудительная установка фокуса ставит его только в начало документа.
Хром, опера, фокс - сохраняют последнее место курсора, но у них вставка через insertNode, а в IE через pasteHTML.
Может что-то делаю не так, подскажите?
|
|
31.10.2011, 00:35
|
Интересующийся
|
|
Регистрация: 05.08.2010
Сообщений: 24
|
|
Продолжаю мучать ie и фокус ввода.
Сделал наихудший вариант: по таймеру(2раз\сек) в текущее положение курсора ставлю метку (пустой именованный span), ну и далее при уходе фокуса вставляю код уже к этой метке.
Наступление фокуса\уход с редактора отслеживаю в переменной через события ифрейма-редактора onfocus\onblur, потому как нормального св-ва то-ли документа, то-ли ифрейма не нашел.
Не решил проблему когда установленный курсор не мигающая каретка, а выделен текст - надо бы ставить метку в конец выделенного текста, но не умею - подскажите как? Тож самое касается когда выделена картинка и таблица.
Дословно: на странице выделено слово из абзаца - необходимо после выделенного текста вставить span.
|
|
31.10.2011, 00:41
|
|
Модератор
|
|
Регистрация: 27.04.2010
Сообщений: 3,417
|
|
У телепатов выходной, простите.
|
|
31.10.2011, 01:25
|
Интересующийся
|
|
Регистрация: 05.08.2010
Сообщений: 24
|
|
Ладно, попробую с картинкой объяснить (в детстве мне тоже не нравились книжки без картинок).
Вот абзац простого текста, левой кнопкой мыши выделяем одно слово.
Необходимо после этого слова средствами JS вставить тег span.
Усложним задачу, выделим 2 слова, тег спан вставить после 2-го слова.
Выделим картинку (ну это уже в редакторе) - span после тега картинки.
Выделим таблицу - тож самое.
Ну и самый неподдающийся момент: вставить html(просто текст) на место span не удалив выделенные слова\объекты.
|
|
31.10.2011, 01:39
|
|
Модератор
|
|
Регистрация: 27.04.2010
Сообщений: 3,417
|
|
Вам не нравятся книжки без картинок, а мне - примеры без кода. Так понятнее?)
Если это iframe - вам нужно гуглить в сторону range-объектов (все нормальные браузеры) и textRange(угадайте, кто). Их функции вполне позволяют решить поставленную вами задачу.
Последний раз редактировалось trikadin, 31.10.2011 в 01:42.
|
|
31.10.2011, 02:16
|
Интересующийся
|
|
Регистрация: 05.08.2010
Сообщений: 24
|
|
// где-то там после создания iframe
if(browser()=="ie"){
setInterval("set_focus('"+field+"')",500);
};
function set_focus(field){
if(ed_view(field)){//если текущий режим текст, а не html
if(gebi("focus_"+field).value==1){//если есть фокус ввода - курсор мигает
if(!ed_range(field).length){//если не выделена картинка\таблица
if(editor(field).getElementById("focus")){//если метка есть - удалим и поставим новую
ed_remove(editor(field).getElementById("focus"));
if(editor(field).getElementById("focus")){
return null;//удаление не получилось - баг
};
};
if(ed_range(field).htmlText==""){//если не выделено слово
editor(field).body.focus();
ed_range(field).pasteHTML("<span id='focus' name='focus'></span>");
};
};
};
};
};
//это ф-я в результате должна вставить текст\html в последнее место курсора
function ins_html(field,txt){
if(browser()=="ie"){
if(editor(field).getElementById("focus")){//если в коде есть метка
var rng=editor(field).body.createTextRange();
rng.moveToElementText(editor(field).getElementById("focus"));
rng.select();//двигаем курсор к метке
editor(field).body.focus();
ed_remove(editor(field).getElementById("focus"));
ed_range(field).pasteHTML(txt);
}else{//метки не было - встанет в начало текста
editor(field).body.focus();
ed_range(field).pasteHTML(txt);
};
}else{
//это для нормальных браузеров
ed_range(field).insertNode(ed_range(field).createContextualFragment(txt));
};
};
Гуглил, читал - такая муть ... думал здесь знающий народ.
http://2007.fastcoder.ru/articles/?aid=609
http://habrahabr.ru/blogs/javascript/55922/
Последний раз редактировалось lurii, 31.10.2011 в 02:23.
|
|
31.10.2011, 13:36
|
|
Модератор
|
|
Регистрация: 27.04.2010
Сообщений: 3,417
|
|
Вот нормальная статья об объектах выделения.
Опишите, как можно более просто и лаконично: что, собственно, вы хотите сделать?
|
|
01.11.2011, 21:54
|
Аспирант
|
|
Регистрация: 18.06.2009
Сообщений: 55
|
|
Интересно вы пишете, что сами разобраться не можете.
1) Если "есть фокус ввода", тогда если "если не выделена картинка"
Комментарий: - либо "выделена картинка", либо "фокус ввода", вам не кажется, что это 2 исключающие друг друга события.
2)Если вы пытаетесь в IE таким образом получить доступ к объектам iframe, - тогда у вас опять ошибка
var iframee_doc=document.getElementById('iframe_id').c ontentWindow.documnt
и только после этого плясать
var el=iframe_doc.getElementById('id_Element')
3) Есть много моментов, ваш код не потянет, ключевой код отсутствует.
Ваша задача ясна, но вы просите разобраться в коде, а не написать за вас скрипт, что было бы наверное проще.
Вот что это такое:
editor(field).body.focus()
После этого вы спрашиваете, почему фокус у body, а не у нужного вам объекта.
"<span id='focus' name='focus'></span>"
Что вообще за манера писать ключевые слова, где не нужно или создавать объекты с одинаковыми идентификаторами, когда есть "class" или обращение к дочерним элементам родителя.
Гугл вам на что, если хотите добавить createContextualFragment в IE, то так и пишите "createContextualFragment in IE", не ужели так сложно(((
Range.prototype.createContextualFragment = function(sHtml){
var f = document.createDocumentFragment(),
var div = document.createElement("div");
f.appendChild(div);
div.outerHTML = sHtml;
return f;}
Лентяи давно все уже за вас написали.
Последний раз редактировалось UDN, 01.11.2011 в 21:58.
|
|
02.11.2011, 16:21
|
Интересующийся
|
|
Регистрация: 05.08.2010
Сообщений: 24
|
|
Благодарю за критику - сразу видно человек в теме!
Начал копать со 2-го пункта:
function editor_frame(field){
/*
for(var i=0;i<window.frames.length;i++){
if(window.frames[i].name==("editor_frame"+field)){
return window.frames[i];
};
};
*/
return document.getElementById("editor_frame"+field).contentWindow;
};
function editor(field){
return editor_frame(field).document;
};
Хорошо что поправили - теперь обращение к фрейму более оптимизировано (а через цикл).
editor(field).body.focus(); - вообще убрал из кода - действительно и без нее все работает.
По 1), мне необходимо запомнить последнюю позицию курсора в редакторе - установить метку span, поэтому первое условие - пользователь ткнул мышкой, но он может ткнуть мышкой не только в текст, но и в картинку\таблицу да еще и выделить текст - поэтому оставить только одно условие не могу - должны подходить все 3: ткнул, не в картинку, не выделил текст.
А если пользователь все-тки выделил текст или ткнул в картинку - необходимо установить метку span после выделенного текста или картинки - выше я задавал этот вопрос как это сделать (даж картинку рисовал).
Если посмотреть на тот же TinyMCE- открыть редактор ( http://www.tinymce.com/tryit/full.php), ткнуть на картинку-логотип справа, нажать на кнопку вставки спец-символа или смайлика - вставить, картинка затерется, а я же хочу чтобы символ\смайлик вставлялись после выделенного объекта.
Проблема увода фокуса ввода есть и tiny - он тоже манипулирует span-метками (__caret), да и "окна" вставки символов\смайлов у него модальные, а у меня - нет, что влечет дополнительные трудности.
Последний раз редактировалось lurii, 02.11.2011 в 17:03.
|
|
04.11.2011, 08:32
|
Аспирант
|
|
Регистрация: 18.06.2009
Сообщений: 55
|
|
В IE эту задачу можно реализовать множеством способов.
Чем больше методов и свойств у браузера, тем медленней он будет работать и наоборот ...тем быстрей.
Не говорите, что норма, что нет.
Я могу утверждать, что у вас, даже нет полного руководства или справочника профессионала по HTML, JAVASCRIPT.
Поэтому такое скудное представление о IE.
Методы отсутствующие в IE, это обертки реализующие данный способ, только написанные в отличие от медленного jvascript, на ...(понятно чём).
Цитата:
|
//это для нормальных браузеров
|
Утверждение не уместно!
1) если нужно после вставки оставить выделение используйте:
function insertNodeIE (sHtml) {with(document.selection.createRange ())collapse (false),pasteHTML (sHtml);}
2) если нужно после вставки установить позицию каретки перед вставляемым объектом:
function insertNodeIE (sHtml) {with(document.selection.createRange ())collapse (false),pasteHTML (sHtml),
collapse (false),select();}
пример: insertNodeIE("<span id='focus' name='focus'></span>")
у редактируемого объекта проверьте состояние атрибута
<div contenteditable="true"><iframe contenteditable="true">
Другие реализации приводить не буду, разберитесь хоть с одной.
Последний раз редактировалось UDN, 04.11.2011 в 11:17.
|
|
|
|