2010-03-22 12 views
6

Sto tentando di aggiungere un attributo quando si utilizza un editor wysiwyg che utilizza il comando "createLink". Ho pensato che sarebbe stato semplice recuperare il nodo che è stato creato dopo che il browse ha eseguito quel comando.Recupera il nodo principale dalla selezione (intervallo) in Gecko e Webkit

Si scopre che sono in grado di afferrare questo nodo appena creato in IE. Qualche idea?

Il codice seguente illustra il problema (registri di debug in occasione del salone fondo output diverso in ogni browser):

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" 

Grazie per qualsiasi aiuto su questo, Ho perlustrato domande relative a SO senza successo!

+0

@ Jason - C'è qualcosa di sbagliato con la mia risposta? Non ho ancora ricevuto alcun tuo commento ... – gnarf

+0

Spiacente, il tuo esempio funziona e il codice è quasi lo stesso di quello che ho appena più compatto. Tuttavia, non funziona ancora per la mia implementazione, mi chiedo se potrebbe avere qualcosa a che fare con l'iframe o l'editor del browser che interferisce. Aggiornerò quando ho completamente funzionante. Grazie per l'aiuto! – Jason

risposta

0

È una soluzione hacky, ma dovrebbe funzionare a meno che qualcuno non crei due collegamenti identici.

this.getSelection() sembra per ottenere la stessa in entrambi i browser non necessario, in modo da:

var link=prompt('gimme link'); 

//add the thing 

var text=this.getSelection(); 

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

Questo è il codice che ho usato per ottenere il "parentNode" del cursore di testo:

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

Ho ottimizzato il mio metodo IE per approssimare il tuo. Testato e funzionante IE8, FF3.6, Safari4, Chrome5. Ho creato un jsbin preview che puoi testare con.

+0

@jason - Vedi anche questa risposta: http://stackoverflow.com/questions/2459180/how-to-edit-a-link-within-a-contenteditable-div/2459214#2459214 potrebbe aiutare ... * alza le spalle * – gnarf

1

Ho trovato che la selezione può diventare complicata e buggy tra i browser. Getta la magia della modifica dei documenti del browser e peggiora!

Ho dato un'occhiata a come TinyMCE implementa ciò che sto cercando di fare e ha adottato lo stesso approccio per modificare jHtmlArea.

Fondamentalmente, viene creato un collegamento con un falso href. Quindi, trova quell'elemento dom cercando i collegamenti con quel particolare href. È quindi possibile aggiungere eventuali attributi desiderati e aggiornare l'href con l'url effettivo.

Il solution above by gnarf è un ottimo esempio di come ottenere un nodo selezionato e funzionerà per la maggior parte degli scenari.

Di seguito si riporta il codice per il mio lavoro in giro:

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); 
Problemi correlati