2010-03-22 4 views
6

Ich versuche, ein Attribut hinzuzufügen, wenn Sie einen WYSIWYG-Editor verwenden, der den Befehl "createLink" verwendet. Ich dachte, es wäre trivial, den Knoten zurück zu bekommen, der erstellt wird, nachdem der Browse diesen Befehl ausgeführt hat.Abrufen von Elternknoten aus Auswahl (Bereich) in Gecko und Webkit

Stellt sich heraus, ich bin nur in der Lage, diesen neu erstellten Knoten in IE zu greifen. Irgendwelche Ideen?

Der folgende Code das Problem (Debug-Protokolle unten zeigen verschiedene Ausgabe in jedem Browser) zeigt:

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" 

Vielen Dank für jede Hilfe zu diesem Thema habe ich Fragen ohne Erfolg auf SO gescheuert!

+0

@ Jason - Gibt es etwas falsch mit meiner Antwort? Ich habe noch kein Feedback von dir gehört ... – gnarf

+0

Sorry, dein Beispiel funktioniert, und der Code ist fast der gleiche wie der, den ich gerade kompakter habe. Allerdings funktioniert es immer noch nicht für meine Implementierung, ich frage mich, ob es etwas mit dem Iframe oder Browser-Editor zu tun haben könnte. Ich werde aktualisieren, wenn ich es voll funktioniere. Danke für die Hilfe! – Jason

Antwort

0

Es ist ein hacky Workaround, sollte aber funktionieren, wenn jemand zwei identische Links macht.

this.getSelection() scheint das gleiche in beiden benötigten Browser zu erhalten, also:

var link=prompt('gimme link'); 

//add the thing 

var text=this.getSelection(); 

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

Dies ist der Code ich verwendet habe, die "parentNode" des Textcursor zu erhalten:

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

Ich habe meine IE-Methode optimiert, um deine zu approximieren. Getestet und funktioniert IE8, FF3.6, Safari4, Chrome5. Ich habe eine jsbin preview eingerichtet, mit der Sie testen können.

+0

@jason - Siehe auch diese Antwort: http://stackoverflow.com/questions/2459180/how-to-edit-a-link-within-a-contenteditable-div/2459214#2459214 könnte helfen ... * zuckt mit den Schultern * – gnarf

1

Ich habe festgestellt, dass die Auswahl in allen Browsern kompliziert und fehlerbehaftet werden kann. Werfen Sie die Magie der Browser-Dokumentbearbeitung, und es wird schlimmer!

Ich schaute mir an, wie TinyMCE implementiert, was ich versuche, und nahm den gleichen Ansatz, um jHtmlArea zu ändern.

Grundsätzlich wird eine Verknüpfung mit einem gefälschten href erstellt. Dann findet es das dom-Element, indem es nach Links mit diesem bestimmten href sucht. Sie können dann beliebige Attribute hinzufügen und die href mit der tatsächlichen URL aktualisieren.

Die solution above by gnarf ist ein großartiges Beispiel für das Abrufen eines ausgewählten Knotens und wird für die meisten Szenarien funktionieren.

Unten ist der Code für meine Arbeit um:

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); 
Verwandte Themen