2010-03-22 60 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);