6

「createLink」コマンドを使用する wysiwyg エディターを使用しているときに、属性を追加しようとしています。ブラウズがそのコマンドを実行した後に作成されたノードを取得するのは簡単だと思いました。

結局のところ、私はこの新しく作成されたノードを 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に関する関連する質問を精査しましたが、成功しませんでした!

4

3 に答える 3

14

これは、テキスト カーソルの「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 プレビューをセットアップしました。

于 2010-03-26T11:42:51.247 に答える
1

ブラウザ間で選択が複雑になり、バグが発生する可能性があることがわかりました。ブラウザのドキュメント編集の魔法を投入すると、さらに悪化します!

私がやろうとしていることを TinyMCE がどのように実装しているかを調べ、同じ方法で jHtmlArea を変更しました。

基本的に、リンクは偽の href で作成されます。次に、その特定の href を含むリンクを検索して、その dom 要素を見つけます。その後、必要な属性を追加して、実際の URL で href を更新できます。

上記の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);
于 2010-05-04T15:10:41.183 に答える
0

これはハックな回避策ですが、誰かが 2 つの同一のリンクを作成しない限りうまくいくはずです。

this.getSelection()必要な両方のブラウザで同じように見えるので、次のようになります。

var link=prompt('gimme link');

//add the thing

var text=this.getSelection();

var whatYouNeed=$('a:contains("'+text+'")[href="'+link+'"');
于 2010-03-26T10:45:01.417 に答える