如何在不计算扩展实体的情况下找到标签(元素)的字符串索引?

时间:2013-05-03 12:48:11

标签: javascript jquery dom innerhtml html-entities

我有一大段文字,我希望能够选择,通过startindexendindex存储所选部分。 (例如,在or中选择word会给我startindex 1和endindex 2。)

这一切都正常,但我对HTML实体有问题,例如&(&符号)。

我创建了一个问题所在的小案例。您可以在下面的小提示中看到,如果您选择startIndex以外的任何内容,&会膨胀,因为它不会将&计为单个字符,而是将5个字符计为:{ {1}}。

有没有办法让它能够恰当地计算像&符号这样的特殊字符,而不会搞砸索引?

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()的{​​{1}}有关。获得indexOftext()的最佳方式是start通过所选文本,因为endindex让我这样做,它是一个从未在应用程序中使用过的HTML标记。

2 个答案:

答案 0 :(得分:3)

如果您真的想使用您的代码并稍微修改一下,您可以使用可见的等效替换所有特殊字符,同时保留html标记... 将startIndex的声明更改为:

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

你可以将replaceces()函数与你想要算作普通字符而不是HTML版本的其他特殊字符一起追加。在我的例子中,我取代了&amp;和“人物。

您的代码中可以使用更多优化方法,这是解决问题的简单方法。

希望这有点帮助,请看这里的分叉小提琴 http://jsfiddle.net/vQNyv/

答案 1 :(得分:1)

问题

使用html()返回:

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

然而,使用text()会返回:

This is a cool test & stuff like that

因此,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解决方案

这是我的解决方案的a 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;
}

取消注释alert()以深入了解正在发生的事情。 nodeType上的Here's a reference


jQuery / DOM解决方案计算outerHTML

根据您的评论,我认为您说想要计算HTML标记(按字符划分),但不是HTML实体。 此功能本身的a new jsFiddle以及此处的a new jsFiddle适用于您的问题。