使用这样的HTML:
<div id="container">
<p>Lorem ipsum lorem ipsum
<p>This is the second!
<span data-attribute="my-span">Hello World</span>
</p>
</p>
</div>
我想找到从容器到我的跨度的文本长度。因此,通过计算后代的指标,我得到了42的正确答案。
但如果我有这样的HTML:
<div id="container">
<p>Lorem ipsum lorem ipsum
<p>This is the second!
<span data-attribute="my-span">Hello World</span>
</p>
Some preceding HTML that I dont want!
</p>
</div>
我不希望字符数继续我的范围。我只希望字符计数达到我的范围,所以正确答案仍然是42.但是通过计算子文本长度,它还会添加前面的文本和span的文本(这很容易通过减去从总数)。
我已经探讨了将html和子字符串列出到我想要的span属性,拆分结束并解析出html,只留下我想要计算的文本字符。但这似乎过于复杂。
我也在考虑使用类似wicked good xpath之类的东西来查找我正在寻找的所有节点,然后总结文本。
我还查看了将所有文本节点列出到某一点并将它们相加,但是它会在我的span文本之前列出子项的前一个文本,因此它的求和顺序不正确。
此外,嵌套可能是n级深,所以不要只假设一个级别。
关于实现这一目标的最佳方法的任何建议?
答案 0 :(得分:2)
一个始终可用的选项是手动遍历DOM树。 jQuery并不擅长处理非元素节点(当我们执行.find('*').contents()
时,似乎所有子节点都列在每个节点的所有子节点之后,而contents
是查看这些节点的唯一方法) ,但我们仍然可以使用本机API。另请注意,处理空格在这里很棘手(我假设您想要折叠空格来模仿渲染器行为)这样的事情:
function countCharsUntil(parent, selector, inclusive){
var done = false;
return listChars(parent).replace(/\s+/g," ").trim().length;
function listChars(elem){
var cn = elem.childNodes;
var chars = "";
if(!inclusive && $(elem).is(selector)){
done = true;
return ""
}
for(var i=0; i<cn.length && !done; i++){
var child = cn[i];
switch(child.nodeType){
case Node.ELEMENT_NODE:
chars += listChars(child);
break;
case Node.TEXT_NODE:
chars += child.nodeValue;
break;
}
}
if(inclusive && $(elem).is(selector)){
done = true;
return chars;
}
return chars;
}
}
测试:http://jsfiddle.net/8hxb6/1/
请注意,测试会返回43个字符以进行独占搜索。这可能是因为你忽略了div>p
里面的“ipsum”和div>p>p
里面的“This”之间的空间
答案 1 :(得分:1)
这位工作人员
$(document).ready(function(){
var tx = $('#container').text().split($('#container span').text())[0].replace(/[\s]{2,}/g,'');
console.log(tx.length); //42
});