2010-03-22 61 views
6

我想在使用使用「createLink」命令的wysiwyg編輯器時添加一個屬性。我認爲在瀏覽器執行那個命令之後找回創建的節點是很簡單的。從Gecko和Webkit中的選擇(範圍)中檢索父節點

原來,我只能在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" 

感謝有這方面的幫助,我已經沖刷上SO相關的問題,但沒有成功!

+0

@jason - 是不是有什麼毛病我的答案嗎?我還沒有收到你的任何反饋信息... – gnarf 2010-03-31 21:18:59

+0

對不起,你的例子確實有效,代碼和我剛纔更緊湊的代碼幾乎一樣。然而,它仍然不適用於我的實現,我想知道它是否可能與iframe或瀏覽器編輯器產生干擾。當我完全正常工作時,我會進行更新。謝謝您的幫助! – Jason 2010-04-01 21:01:40

回答

0

這是一個怪異的解決方法,但應該工作,除非有人制作兩個相同的鏈接。

this.getSelection()似乎得到相同的兩個需要瀏覽器,因此:

var link=prompt('gimme link'); 

//add the thing 

var text=this.getSelection(); 

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

這是我用來獲取文本光標的「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 preview

+0

@jason - 也見這個答案:http://stackoverflow.com/questions/2459180/how-to-edit-a-link-within-a-contenteditable-div/2459214#2459214可能會幫助... *聳聳肩* – gnarf 2010-05-04 17:40:02

1

我發現,選擇可能會變得複雜和錯誤跨瀏覽器。拋出瀏覽器文檔編輯的魔力,它變得更糟!

我看了一下TinyMCE如何實現我正在做的事情,並採取了同樣的方法來修改jHtmlArea。

基本上,鏈接是用假href創建的。然後,它通過搜索該特定href的鏈接來發現dom元素。然後,您可以添加任何所需的屬性並使用實際url更新href。

solution above by 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);