【问题标题】:Retrieve parent node from selection (range) in Gecko and Webkit从 Gecko 和 Webkit 中的选择(范围)中检索父节点
【发布时间】:2010-03-22 17:02:36
【问题描述】:

我试图在使用使用“createLink”命令的所见即所得编辑器时添加一个属性。我认为取回浏览器执行该命令后创建的节点是微不足道的。

原来,我只能在 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 的相关问题,但没有成功!

【问题讨论】:

  • @jason - 我的回答有问题吗?我还没有收到您的任何反馈...
  • 对不起,您的示例确实有效,并且代码与我的代码几乎相同,只是更紧凑。但是,它仍然不适用于我的实现,我想知道它是否与 iframe 或浏览器编辑器的干扰有关。当我完全工作时,我会更新。感谢您的帮助!

标签: javascript webkit gecko


【解决方案1】:

这是我用来获取文本光标的“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,您可以使用它进行测试。

【讨论】:

【解决方案2】:

我发现跨浏览器的选择会变得复杂和错误。加入浏览器文档编辑的魔力,情况会变得更糟!

我看了一下 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);

【讨论】:

    【解决方案3】:

    这是一个 hacky 解决方法,但除非有人创建两个相同的链接,否则应该可以工作。

    this.getSelection() 在所需的浏览器中似乎都一样,所以:

    var link=prompt('gimme link');
    
    //add the thing
    
    var text=this.getSelection();
    
    var whatYouNeed=$('a:contains("'+text+'")[href="'+link+'"');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 2011-02-26
      • 1970-01-01
      相关资源
      最近更新 更多