2

http://jsfiddle.net/m45uM/

タグでの置換は正常に機能しますが、編集可能な div 内の最初の位置に設定されます。

どうすればこれを修正できますか? また、Twitter のようにキャレットをタグ内に配置しているイベントをトリガーするにはどうすればよいですか?

function replacer(match, p1, p2, p3, offset, string) {
    var name = '';
    var user = '';
    $.each(ar.data, function (i, item) {
        var keyword = match.substring(1, (match.length - 1));
        if (keyword == item.name) {
            user = item.user;
            name = item.name;
        }
    });
    return '<a href="/' + user + '">' + name + '</a>';
}
$(document).ready(function (e) {
    $('body').on('keyup', '#cont', function (e) {
        var cont = $('#cont').html();
        var cont2 = cont.replace(/\@\w+\s/gi, replacer);
        $('#cont').html(cont2);
        console.log($('#cont').html());
    });
});
var ar = {
    "data": [{
        "user": "testuser1",
            "name": "testname1"
    }, {
        "user": "testuser2",
            "name": "testname2"
    }]
};
console.log(ar);
4

1 に答える 1

0

これを試みる前に、いくつかのことを行います。

  1. 要素を文字列として dom に追加しないでください - "return .."。このノードで他のアクションを実行するのは難しいでしょう。代わりに、DOM API (作成/削除/置換/追加など) を使用してこれらの機能を実行することをお勧めします。私の提案は、読み進めていくうちに明確になります。

  2. 新しい文字列を返し、HTML をその特定の文字列にやみくもに設定すると、その前のすべてのテキストが失われます。例: Hello my name is @testuser1 は @ のみになります。「Hello my name is」は失われます。

解決:

ニンジンの配置を管理するには、ユーザーの選択を覚えておく必要があります。注 - HTML を変更すると、ブラウザはこの選択を失います。したがって、これを手動で追跡する必要があります。

テキストを「置換」する前に、次の方法で選択を取得できます。

//IE & Others
if (window.getSelection) {
    userSelection = window.getSelection();
} else if (document.selection) {
    userSelection = document.selection.createRange();
}
selectedNode = userSelection.anchorNode;
selectedOffset = userSelection.anchorOffset;

テキストを置き換えた後、選択をコンテナに戻す必要があります。

//IE & Others


var range,
        selection;
    if (window.getSelection) {
        selection = window.getSelection();
        range = document.createRange();
        range.setStart(targetElement, targetOffset);
        range.setEnd(targetElement, targetOffset);
        selection.removeAllRanges();
        selection.addRange(range);
    } else if (document.selection) {
        range = document.selection.createRange();
        range.moveToElementText(targetElement.parentElement);
        range.collapse(true);
        range.moveEnd('character', targetOffset);
        range.moveStart('character', targetOffset);
        range.select();
    }
}

ターゲット要素とターゲット オフセットは、ターゲットにするノードと、カーソルを配置する位置 (左から) です。

基本が終わったので、次は難しい部分です。

  • アンカー要素を入れてテキスト (TextNode) を分割する場合、ターゲット要素をアンカー要素とし、オフセットをアンカー要素内のテキストの長さにする必要があります。DOM API を使用し、この要素を変数として格納すると、これははるかに簡単になります。

  • ユーザーがテキストの任意の部分に移動して @username1 と入力する可能性がある状況に対応する必要があります。これはかなり単純なはずです。

これを実現するために、Rangy JS lib をいじることもできます。

楽しむ!

于 2013-09-03T22:16:16.330 に答える