Я пытаюсь добавить атрибут при использовании WYSIWYG-редактора, который использует команду "createLink". Я думал, что это будет тривиально для возвращения узла, который создается после того, как обзор выполняет ту команду.
Оказывается, я только могу захватить этот недавно созданный узел в IE. Какие-либо идеи?
Следующий код демонстрирует проблему (журналы отладки в основе показывают другой вывод в каждом браузере):
var getSelectedHTML = function() {
if ($.browser.msie) {
return this.getRange().htmlText;
} else {
var elem = this.getRange().cloneContents();
return $("<p/>").append($(elem)).html();
}
};
var getSelection = function() {
if ($.browser.msie) {
return this.editor.selection;
} else {
return this.iframe[0].contentDocument.defaultView.getSelection();
}
};
var getRange = function() {
var s = this.getSelection();
return (s.getRangeAt) ? s.getRangeAt(0) : s.createRange();
};
var getSelectedNode = function() {
var range = this.getRange();
var parent = range.commonAncestorContainer ? range.commonAncestorContainer :
range.parentElement ? range.parentElement():
range.item(0);
return parent;
};
// **** INSIDE SOME EVENT HANDLER ****
if ($.browser.msie) {
this.ec("createLink", true);
} else {
this.ec("createLink", false, prompt("Link URL:", "http://"));
}
var linkNode = $(this.getSelectedNode());
linkNode.attr("rel", "external");
$.log(linkNode.get(0).tagName);
// Gecko: "body"
// IE: "a"
// Webkit: "undefined"
$.log(this.getSelectedHTML());
// Gecko: "<a href="http://site.com">foo</a>"
// IE: "<A href="http://site.com" rel=external>foo</A>"
// Webkit: "foo"
$.log(this.getSelection());
// Gecko: "foo"
// IE: [object Selection]
// Webkit: "foo"
Спасибо за любую справку на этом я обыскивал связанные вопросы на ТАК без успеха!
Это код, который я использовал для получения "parentNode" текстового курсора:
var getSelectedNode = function() {
var node,selection;
if (window.getSelection) {
selection = getSelection();
node = selection.anchorNode;
}
if (!node && document.selection) {
selection = document.selection
var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
node = range.commonAncestorContainer ? range.commonAncestorContainer :
range.parentElement ? range.parentElement() : range.item(0);
}
if (node) {
return (node.nodeName == "#text" ? node.parentNode : node);
}
};
Я настроил свой метод IE, чтобы он приблизился к вашему. Протестировано и работает IE8, FF3.6, Safari4, Chrome5. Я установил предварительный просмотр jsbin , с помощью которого вы можете протестировать.
Это хаковый обходной кулин, но он должен работать, если кто-то не сделает две одинаковые ссылки.
this.getSelection()
, похоже, получает одинаковое в обоих необходимых браузерах, поэтому:
var link=prompt('gimme link');
//add the thing
var text=this.getSelection();
var whatYouNeed=$('a:contains("'+text+'")[href="'+link+'"');
Я обнаружил, что выбор может быть сложным и глючным в разных браузерах. Добавьте магию редактирования документов в браузере, и это станет еще хуже!
Я посмотрел, как TinyMCE реализует то, что я пытаюсь сделать, и принял тот же подход к изменению jHtmlArea.
В основном, ссылка создается с поддельным href. Затем он находит этот элемент dom, ища ссылки с этим конкретным href. Затем можно добавить любые желаемые атрибуты и обновить href фактическим URL-адресом.
Приведенное выше решение от gnarf является отличным примером получения выбранного узла и будет работать для большинства сценариев.
Ниже приведен код для моего обходного времени:
var url = prompt("Link URL:", "http://");
if (!url) {
return;
}
// Create a link, with a magic temp href
this.ec("createLink", false, "#temp_url#");
// Find the link in the editor using the magic temp href
var linkNode = $(this.editor.body).find("a[href='#temp_url#']");
linkNode.attr("rel", "external");
// Apply the actual desired url
linkNode.attr("href", url);