如何在不计算扩展实体的情况下找到标记(元素)的字符串索引?
How do I find the string index of a tag (an element) without counting expanded entities?
我有一大块文本,我希望能够选择,通过其startindex
和endindex
存储所选部分。(例如,在word
中选择or
将得到startindex
1
和endindex 2
。)
这一切工作正常,但我有一个问题与HTML实体,如&
(&)。
我创建了一个问题包含的小案例。您可以在下面的图中看到,如果您选择&
以外的任何内容,startIndex
会膨胀,因为它不会将&
计算为单个字符,而是将&
计算为5个字符:
是否有一种方法可以使它正确计数特殊字符,如&,而不会搞砸索引?
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()
用来做indexOf
而不是text()
有关。获得start
和endindex
的最好方法是通过选定的文本来获取<strike>
,因为execCommand
让我这样做,它是一个从未在应用程序中使用过的HTML标签。
如果你真的想使用你的代码,只是稍微修改一下,你可以用可见的等效替换所有特殊字符,同时保留html标签…将startIndex的声明更改为:
var startIndex = $('#textBlock').html().replace(/&/g, "&").replace(/"/g, "'"").indexOf('<strike>');
你可以在replaces()函数后面加上你想算作普通字符的其他特殊字符,而不是它们的HTML版本。在我的例子中,我替换了&和"字符。
有更多的优化可能在你的代码,这是一个简单的方法来解决你的问题。
希望这有助于一点,看到这里的分叉小提琴http://jsfiddle.net/vQNyv/
问题
使用html()
返回:
This is a cool test & <strike>stuff like</strike> that
使用text()
将返回:
This is a cool test & stuff like that
因此,html()
是必要的,以便看到字符串, <strike>
,但是当然,所有特殊实体都被转义了,它们应该是。有很多方法可以解决这个问题,但是想象一下,如果文本描述的是HTML本身,会发生什么:
Use the <strike></strike> tags to strike out text.
在这种情况下,想要的解释,
Use the <strike></strike> 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;
}
取消注释alert()
s以深入了解发生了什么。以下是nodeType
s的参考。
jQuery/DOM解决方案计数outerHTML根据你的评论,我认为你是在说你确实想要计算HTML标签(按字符计算),而不是HTML实体。这是函数本身的新jsFiddle,这是它应用于你的问题的新jsFiddle
- 如何索引jquery中的每个元素
- JavaScript DOM:在容器中查找元素索引
- 通过javascript中的元素索引访问eventListener中的元素
- 将页面元素索引到 JSON 对象?或者jQuery选择器它每次
- jQuery将相同的类添加到两个不同容器中的同一元素索引中
- 获取小元素索引直到数组长度
- jQuery获取元素索引,尽管包装器/父元素
- 更改数组中某些元素(索引)的顺序
- 访问具有公共类名的元素数组中的元素索引
- 访问循环的内部的ES6数组元素索引
- 列表类元素(索引).渐变(某些速度)不起作用
- javascript中的表单元素索引,用于jquery.change函数
- 获取文本块中的元素索引
- 用主干JS .get模型事件连接元素索引
- 从81个元素索引的数组中获取行和列值
- 如何使用javascript获得元素索引
- 使用类和子类获取元素索引
- Mootools从父元素获取子元素索引
- 如何在Javascript中获得一组固定元素的元素索引
- 使用jQuery更改列表元素索引