Вставить текст в текущую позицию курсора в раскрывающемся списке, измененном внутри iframe
Я использую текстовый редактор, предоставленный Microsoft ajax-toolkit.
Он отображает iframe
в браузере. Я добавил раскрывающийся список в этом редакторе, и я хочу, чтобы при изменении индекса раскрывающегося списка значение должно быть добавлено в текущую позицию курсора в редакторе.
У меня есть код на SO, который дает мне текущий выделенный текст внутри редактора следующим образом
function getIframeSelectionText(iframe) {
var win = iframe.contentWindow;
var doc = iframe.contentDocument || win.document;
if (win.getSelection) {
return win.getSelection().toString();
} else if (doc.selection && doc.selection.createRange) {
return doc.selection.createRange().text;
}
}
Но я хочу добавить текст в текущую позицию. Html отображается как ниже
<td class="ajax__htmleditor_editor_editpanel"><div id="Editor1_ctl02" style="height:100%;width:100%;">
<iframe id="Editor1_ctl02_ctl00" name="Editor1_ctl02_ctl00" marginheight="0" marginwidth="0" frameborder="0" style="height:100%;width:100%;display:none;border-width:0px;">
</iframe><textarea id="Editor1_ctl02_ctl01" class="ajax__htmleditor_htmlpanel_default" style="height:100%;width:100%;display:none;"></textarea><iframe id="Editor1_ctl02_ctl02" name="Editor1_ctl02_ctl02" marginheight="0" marginwidth="0" frameborder="0" style="height:100%;width:100%;display:none;border-width:0px;">
</iframe>
</div></td>
Я стараюсь следовать
$("#imgDropdown").change(function () {
//var iframeBody = $(window.Editor1_ctl02_ctl00.document.getElementsByTagName("body")[0]);
var iframe = document.getElementById("Editor1_ctl02_ctl00");
$("#Editor1_ctl02_ctl00").find("body").insertAtCaret("value");
//alert(getIframeSelectionText(iframe));
});
функция вставки текста не работает с iframe
, как следует
$.fn.extend({
insertAtCaret: function (myValue) {
if (document.selection) {
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
}
else if (this.selectionStart || this.selectionStart == '0') {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var scrollTop = this.scrollTop;
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
this.focus();
this.selectionStart = startPos + myValue.length;
this.selectionEnd = startPos + myValue.length;
this.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
}
})
Ответы
Ответ 1
Легко, вам просто нужно использовать.
$( "# Editor1_ctl02_ctl00" ) содержание() найти ( 'текстовое поле') insertAtCaret ( 'значение');...
Обновление
Извините, я думал, что функция insertAtCaret работает для вас, вам просто нужно работать внутри iFrame. Вы можете использовать эту версию insertAtCaret:
jQuery.fn.extend({
insertAtCaret: function (html) {
var winObject = function (el){
var doc = el.ownerDocument;
return doc.defaultView || doc.parentWindow
};
return this.each(function (i) {
var sel, range, w = this;
w = winObject(w);
if (w.getSelection) {
// IE9 and non-IE
sel = w.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = w.document.createElement("div");
el.innerHTML = html;
var frag = w.document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (w.document.selection && w.document.selection.type != "Control") {
// IE < 9
w.document.selection.createRange().pasteHTML(html);
}
}
)
}
});
и назовите его так:
$( "# Editor1_ctl02_ctl00" ) содержание() найти ( 'тело') insertAtCaret ($ Вэл)...
Функция, адаптированная из здесь
Счастливое кодирование!
Ответ 2
Здесь, кажется, несколько проблем.
-
В редакторе Microsoft ajax-toolkit создается iframe, где включено свойство designMode
, и почему оно редактируется, он не имеет значения, а textNodes добавляются прямо к телу, что делает его немного сложнее.
-
Когда вы выбираете что-то из выпадающего списка, основное внимание уделяется выпадающему меню, и нет позиции каретки, так как фокус смещается от iFrame.
Я предполагаю, что выпадающий список находится в верхней строке редактора или где-либо еще, что находится за пределами iFrame.
Кроме того, в редакторе Microsoft ajax-toolkit есть рекомендуемое обновление, HTMLEditorExtender.
Код, который вы должны зафиксировать в позиции каретки, кажется, предназначен для обычного ввода /textarea, и вам придется адаптировать этот код для работы с любым Node внутри iframe, который находится в designMode, с его собственным окном и документ и т.д.
Учитывая приведенные выше соображения, это то, что я придумал для этого.
var frameID = 'Editor1_ctl02_ctl00',
selectID = 'imgDropdown',
iframe = document.getElementById(frameID),
iWin = iframe.contentWindow ? iframe.contentWindow : window.frames[frameID];
$(iWin).on('blur', function() {
$(iframe).data('range', getRange(iWin));
});
$('#' + selectID).on('change', function() {
var range = $(iframe).data('range');
addText(iWin, range, this.value);
});
function getRange(win) {
var sel, range, html;
if (win.getSelection) {
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
}
} else if (win.document.selection && win.document.selection.createRange) {
range = win.document.selection.createRange();
}
return range;
}
function addText(win, range, text) {
if (win.getSelection) {
range.insertNode(win.document.createTextNode(text));
} else if (win.document.selection && win.document.selection.createRange) {
range.text = text;
}
}
FIDDLE