2010-03-22 7 views
6

Próbuję dodać atrybut podczas korzystania z edytora WYSIWYG, który używa polecenia "createLink". Sądziłem, że odzyskanie węzła utworzonego po przeglądaniu tego polecenia będzie trywialne.Odzyskiwanie węzła nadrzędnego z zaznaczenia (zakresu) w Gecko i pakiecie Webkit

Okazuje się, że mogę pobrać ten nowo utworzony węzeł tylko w IE. Jakieś pomysły?

Poniższy kod demonstruje problem (dzienniki debugowania na dole przedstawiają różne wyjścia w zależności od przeglądarki):

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" 

Dzięki za pomoc w tej sprawie, mam prana pytania związane z na SO bez powodzenia!

+0

@jason - Czy jest coś nie tak z moją odpowiedź? Nie otrzymałem jeszcze od Ciebie żadnych opinii ... – gnarf

+0

Niestety, twój przykład działa, a kod jest prawie taki sam jak ten, który mam po prostu bardziej kompaktowy. Jednak nadal nie działa dla mojej realizacji, zastanawiam się, czy może to mieć coś wspólnego z ingerencją elementu iframe lub edytora przeglądarki. Będę aktualizował, gdy mam go w pełni sprawny. Dzięki za pomoc! – Jason

Odpowiedz

0

To jest hacky rozwiązanie, ale powinno działać, chyba że ktoś tworzy dwa identyczne linki.

this.getSelection() wydaje się taka sama w obu potrzebnego przeglądarce, więc:

var link=prompt('gimme link'); 

//add the thing 

var text=this.getSelection(); 

var whatYouNeed=$('a:contains("'+text+'")[href="'+link+'"'); 
13

Jest to kod Użyłem aby uzyskać "parentNode" kursora tekstowego:

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); 
    } 
}; 

Poprawiłem moją metodę IE, aby zbliżyć się do twojej. Testowane i działające IE8, FF3.6, Safari4, Chrome5. Skonfigurowałem jsbin preview, z którym można testować.

+0

@jason - Zobacz także tę odpowiedź: http://stackoverflow.com/questions/2459180/how-to-edit-a-link-within-a-contenteditable-div/2459214#2459214 może pomóc ... * wzrusza ramionami * – gnarf

1

Zauważyłem, że selekcja może być skomplikowana i kłopotliwa w różnych przeglądarkach. Wrzuć magię edytowania dokumentów przeglądarki, a robi się coraz gorzej!

Przyjrzałem się, jak TinyMCE wdraża to, co próbuję zrobić, i podjął to samo podejście, aby zmodyfikować jHtmlArea.

Zasadniczo link jest tworzony za pomocą fałszywego href. Następnie znajduje element dom, szukając linków z tym konkretnym hrefem. Następnie możesz dodać dowolne wymagane atrybuty i zaktualizować href za pomocą rzeczywistego adresu URL.

Model solution above by gnarf jest doskonałym przykładem na uzyskanie wybranego węzła i będzie działał w większości scenariuszy.

Poniżej znajduje się kod dla mojej pracy w okolicy:

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); 
Powiązane problemy