0

Rangyを使用して、リッチテキストエディター(designmode = "on")でいくつかの操作を実行しています。これらの機能の1つは、ユーザーが事前に作成した特定の事前定義された文字を表すことができるフォーマットされたコンテンツを貼り付けることです。すべてのテキストコンテンツは段落要素で保持されます。ユーザーはこれから始めることができます:

<p>The following is a special character: |</p>

ここで、パイプ(|)はキャレット位置です。次に、エディターのボタンを使用して「特殊」文字の1つを貼り付けることを選択し、最終的に次のようになります。

<p>The following is a special character: <span class="read-only" contenteditable="false">SPECIAL</span>|</p>

このアクションでは、Rangyを舞台裏で使用して、内部貼り付けプロセス中にキャレット(SelectionSaveRestoreModule)の位置を維持します。これは、エディターでテキストを後貼り付け処理する可能性があり、そうでない場合はカーソルの位置を台無しにする可能性があります。

<span>ただし、IE8では、無効な位置にするバグがあるように見えるため、キャレットを後に配置することはできません。その結果、カーソルは<span>要素の前に表示され、キーボードのカーソルコントロールでスパンの後にカーソルを移動することさえできません。実際、カーソルが次の段落に移動するのを防ぎます。

私は最近、いくつかのテクニックを試しました。たとえば、<span>sの後に余分な文字を配置して成功するなどです。ただし、これらの余分な文字は、表示されたときにユーザーに明らかに混乱を引き起こし、理想的ではありません。ゼロ幅スペースを使用する方が視覚的には優れていますが、貼り付け操作の後でそれらを整理しようとすると問題が発生します。

特殊文字に対するこのユーザー要件をサポートするための「整頓された」方法が必要であり、間違った方法でこれにアプローチしている可能性があることを自由に受け入れます。

4

1 に答える 1

0

これまでのテストで機能しているように見える解決策がありますが、それを見ると、もっと良い方法があるはずだという気持ちで満たされています(恐怖感は言うまでもありません)。

このコードが行おうとしているのは、段落の終わりにある読み取り専用スパンの後にゼロ幅スペースを配置することです。これは、これらの要素の後のノードを調べて、実際にテキストが含まれているかどうかを判断することによって行われます。同時に、以前の検査からテキストに残っている可能性のあるゼロ幅スペースを削除しますが、現在は不要になっています。

var ZWS = '\ufeff';

jQuery(_doc.body).find('p').each(function () {
    var lastContentEditable = undefined;
    // Look through the root contents of each paragraph to remove no-longer require zws fixes
    jQuery(this).contents().each(function () {
         if (this.nodeType === 3) {
            if (this.nodeValue.indexOf(ZWS) != -1) {
                // Text node containing a ZWS - remove for now
                this.nodeValue = this.nodeValue.replace(new RegExp(ZWS, 'g'), '');
            }

            // Does this node now contain text?
            if (this.nodeValue.length > 0 && lastContentEditable) {
                // Found text after a read-only node, ergo we do not need to modify that read-only node at the end
                lastContentEditable = undefined;
            }
        } else if (this.nodeType === 1 && this.getAttribute('contenteditable') === "false") {
            // Indicate that this is currently the last read-only node
            lastContentEditable = this;
        }
    });

    if (lastContentEditable) {
        // It appears that there is a read-only element at the end of the paragraph.
        // Add the IE8 fix zws after it.
        var node = document.createTextNode(ZWS);
        jQuery(lastContentEditable).after(node);
    }

});
于 2012-07-30T11:27:29.283 に答える