1

選択できるようにしたい大きなテキストがあり、選択した部分をstartindexandで保存しますendindex。(たとえば、orinwordを選択すると mestartindex 1と endindexが返され2ます。)

これはすべて正常に動作しますが、&(アンパサンド) などの HTML エンティティに問題があります。

私は問題が構成されている小さなケースを作成しました。以下のフィドルで、 を超えるものを選択すると が膨張することがstartIndexわかります。&&&

インデックスを台無しにすることなく、アンパサンドなどの特殊文字を適切にカウントする方法はありますか?

http://jsfiddle.net/Eqct4/

JavaScript


$(document).ready(function() {
    $('#textBlock').mouseup(function() {
        var selectionRange = window.getSelection();
        if (!selectionRange.isCollapsed) {
            selectedText = selectionRange.getRangeAt(0).toString();
        }

        document.getElementById('textBlock').setAttribute('contenteditable', true);
        document.execCommand('strikethrough', false);
        var startIndex = $('#textBlock').html().indexOf('<strike>');
         $('#startindex').html('the startindex is: ' + startIndex);
        done();
    });
});

function done() {
    document.getElementById('textBlock').setAttribute('contenteditable', false);
    document.getSelection().removeAllRanges();
    removeStrikeFromElement($('#textBlock'));
}

function removeStrikeFromElement (element) {
    element.find('strike').each(function() {
        jQuery(this).replaceWith(removeStrikeFromElement(jQuery(this)));
    });
    return element.html();
}

私はそれが の代わりに$('#textBlock').html()を行うことに関係していると思う/知っている. andを取得する最善の方法は、選択したテキストを通過することでした。これは、アプリケーションで使用されることのない HTML タグであるためです。indexOftext()startendindex<strike>execCommand

4

2 に答える 2

3

本当に自分のコードを使用して少しだけ変更したい場合は、html タグを保持したまま、すべての特殊文字を目に見える同等のものに置き換えることができます... startIndex の宣言を次のように変更します。

var startIndex = $('#textBlock').html().replace(/&amp;/g, "&").replace(/&quot;/g, "\"").indexOf('<strike>');

replaces() 関数に、HTML バージョンではなく通常の文字として数えたい他の特殊文字を追加できます。私の例では、 & と " の文字を置き換えました。

コードにはさらに多くの最適化が可能であり、これは問題を解決する簡単な方法です。

これが少し役立つことを願っています。ここでフォークされたフィドルを参照してください http://jsfiddle.net/vQNyv/

于 2013-05-03T13:11:21.250 に答える
1

問題

html()返品の使用:

This is a cool test &amp; <strike>stuff like</strike> that

ただし、を使用するtext()と、以下が返されます。

This is a cool test & stuff like that

そのため、文字列,html()を表示するには が必要ですが、もちろんすべての特殊エンティティはエスケープされる必要があります。この問題を回避する方法はいくつかありますが、たとえば、テキストが HTML 自体を記述しているとしたらどうなるか想像してみてください。<strike>

Use the <strike></strike> tags to strike out text.

この場合、解釈が必要です。

Use the &lt;strike&gt;&lt;/strike&gt; tag to strike out text.

そのため、これにアプローチする唯一の正しい方法は、DOM ノードを反復処理することです。


jQuery/DOM ソリューション

これが私のソリューションのjsFiddleであり、コードは次のとおりです。

jQuery.fn.indexOfTag = function (tag) {
    var nodes = this[0].childNodes;
    var chars = 0;
    for (var i = 0; nodes && i < nodes.length; i++) {
        var node = nodes[i];
        var type = node.nodeType;
        if (type == 3 || type == 4 || type == 5) {
            // alert('advancing ' + node.nodeValue.length + ' chars');
            chars += node.nodeValue.length;
        } else if (type == 1) {
            if (node.tagName == tag.toUpperCase()) {
                // alert('found <' + node.tagName + '> at ' + chars + ', returning');
                return chars;
            } else {
                // alert('found <' + node.tagName + '>, recursing');
                var subIndexOfTag = $(node).indexOfTag(tag);
                if (subIndexOfTag == -1) {
                    // alert('did not find <' + tag.toUpperCase() + '> in <' + node.tagName + '>');
                    chars += $(node).text().length;
                } else {
                    // alert('found <' + tag.toUpperCase() + '> in <' + node.tagName + '>');
                    chars += subIndexOfTag;
                    return chars;
                }
            }
        }
    }
    return -1;
}

s のコメントを外して、alert()何が起こっているのかを理解してください。Sの参考書はこちらnodeType


outerHTML をカウントするjQuery/DOM ソリューション

あなたのコメントに基づいて、HTMLタグを(文字単位で)数えたいと言っていると思いますが、HTMLエンティティだけではありません。これは関数自体の新しい jsFiddle であり、​​題に適用された新しい jsFiddleです。

于 2013-05-03T13:55:08.373 に答える