Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > pasteHTML в iframe в Opera


Автор: Atlete 8.1.2010, 10:38
столкнулся с такой задачей как вставка произвольного HTML кода в iframe.
Чтобы было сразу понятнее задача связанная с WYSIWYG-редактором.

есть такой код:
Код

var isGecko = navigator.userAgent.toLowerCase().indexOf("gecko") != -1;
var iframe = (isGecko) ? document.getElementById(iframe_id) : frames[iframe_id];
var iDoc = (isGecko) ? iframe.contentDocument : iframe.document;
var el=document.createElement('div');
el.innerHTML = 'hello world!';


if(!isGecko){
        // IE
        var rng = iDoc.selection.createRange();
        rng.pasteHTML(el.outerHTML);
    }else{
        // gecko
        iframe.contentWindow.getSelection().getRangeAt(0).insertNode(node);    
    }


Такой код работает во всех браузерах (проверял в ИЕ, Mozilla и Chrome) кроме Opera. 

Я знаю что способ вставки HTML кода есть. Все что на гуглил показывало аналогичный пример.
Что я делаю не так? 
Помогите найти решение.

Автор: Amphiluke 8.1.2010, 11:28
Что-то как будто много лишнего…

Код

var ifrWnd = document.getElementById(iframe_id).contentWindow;
var el = ifrWnd.document.createElement("div");
el.innerHTML = "hello world!";
ifrWnd.document.getElementsByTagName("body")[0].appendChild(el);

Автор: Atlete 8.1.2010, 12:05
если сделать appendChild то HTML добавиться в конец. 
А суть в WYSIWYG редакторе добавлять именно там где стоит курсор.
Так что указанный вами метод не подойдет.

Автор: Amphiluke 8.1.2010, 13:15
Метод pasteHTML() понимает только IE. Opera — нет. Поэтому пересмотрите свою методику определения браузера. Opera будет нормально выполнять то, что что вы прописали для Gecko. Поэтому лучше сделать прооверку: 
Код

если (IE) то {
   вставка ч/з pasteHTML()
} иначе {
   вставка ч/з insertNode()
}


Добавлено через 10 минут и 56 секунд
Код

function pasteDiv() {
    var notIE = (window.addEventListener) ? true : false;
    var ifrWnd = document.getElementById(iframe_id).contentWindow;
    var iDoc = ifrWnd.document;
    var el = iDoc.createElement("div");
    el.innerHTML = "hello world!";
    if (notIE) {
        ifrWnd.getSelection().getRangeAt(0).insertNode(el);
    } else {
        var rng = iDoc.selection.createRange();
        rng.pasteHTML(el.outerHTML);
    }
}

Автор: Atlete 8.1.2010, 13:28
к сожалению это не так.

пробуем сделать так

Код

...
alert(iframe.contentWindow.getSelection());
...


результат undefined

но если сделать так:
Код

...
alert(iDoc.selection);
...


объект есть.
Получается для ИЕ и Оперы надо использовать одинаковый метод.
Но у обекта Range (CreateRange() ) в ИЕ гораздо больше методов, чем в Опере.

Не хочется делать все через реплейсы...как то не интересно получается (((.

Автор: Amphiluke 8.1.2010, 13:34
Я привел вам рабочий код в предыдущем сообщении. 
Код

alert(ifrWnd.getSelection());

в Opera показывает что требуется. Никаких undefined.

Автор: Atlete 8.1.2010, 13:50
Огромное спасибо. Верхний пост не видел.
Вставляется HTML.

Автор: Amphiluke 8.1.2010, 13:51
В вашем коде isGecko = false в случае Opera, и поэтому iframe определяется через коллекцию frames, как для IE, а не через getElementById. Но возвращаемый таким образом объект окна не имеет свойства contentWindow (оно возвращается как undefined), поэтому и метод getSelection() в этом случае у вас не определяется в Opera.

Ой, не успел… =)

Автор: Atlete 8.1.2010, 14:06
Я уже разобрался по Вашему коду. Большое спасибо за оказанную помощь еще раз.
К сожалению не могу плюсануть - не хватает еще кол-в сообщений.

Автор: Frozen_Coyote 6.2.2011, 12:22
Цитата(Atlete @ 8.1.2010,  14:06)
Я уже разобрался по Вашему коду. Большое спасибо за оказанную помощь еще раз.
К сожалению не могу плюсануть - не хватает еще кол-в сообщений.

А не подскажете, как модифицировать код для Оперы, чтобы вставка происходила не в место, где курсор стоит, а замещая выделенный текст или объект?

спасибо!

Автор: Amphiluke 6.2.2011, 16:19
Для браузеров, кроме Opera, можно перед вставкой элемента вызывать метод deleteFromDocument() объекта Selection (а для IE — метод clear()). В Opera такой «фокус» не проходит. Для нее уже до нас придумали http://help.dottoro.com/ljdslife.php#example_1.


Похоже, эти обходные пути уже тоже не работают... smile

Автор: Amphiluke 6.2.2011, 17:07
Придумал для Opera другой обходной путь. Довольно извращенный, но рабочий.  smile 

Код

function pasteDiv(iframe_id) {
    var notIE = (window.addEventListener) ? true : false;
    var ifrWnd = document.getElementById(iframe_id).contentWindow;
    var iDoc = ifrWnd.document;
    var el = iDoc.createElement("div");
    el.innerHTML = "hello world!";
    if (notIE) {
        var sel = ifrWnd.getSelection();
        sel.deleteFromDocument();
        if (!ifrWnd.getSelection().isCollapsed) { // Opera, it's specially for you
            var tmpspan = iDoc.createElement("span");
            ifrWnd.getSelection().getRangeAt(0).surroundContents(tmpspan);
            tmpspan.parentNode.removeChild(tmpspan);
        }
        ifrWnd.getSelection().getRangeAt(0).insertNode(el);
    } else {
        var rng = iDoc.selection.createRange();
        rng.pasteHTML(el.outerHTML);
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)