2

我想使用 jQuery 自定义选择器从 DOM 元素中提取文本。它应该只选择没有标记兄弟的文本节点(很像 XPath 中的 /text() )。

背景:我正在开发一个 Firefox 扩展,它可以在非常不同的网站上提取一些特定信息(例如用户名)。现在我希望我的用户能够通过尽可能简单的表单为新网站动态添加路径定义:

添加新网站:

网址:_ __ _ __ _ __ _ __ _ ___(例如“http://stackoverflow.com/questions/”)

路径:_ __ _ __ _ __ _ __ _ ___(例如,“.user-details>a:eq(0)”代表提出问题的用户名)

例如,在 stackoverflow 上, $(path).text() 将用户名作为文本返回。但是在其他一些站点上,用户名只能作为带有兄弟姐妹标签的文本节点使用,如下例所示:

<div id="person">
    johndoe <span id="age">(57)</span>
    <span id="description">Lorem ipsum dolor sit amet…&lt;/span>
</div>

由于 jQuery 没有为文本节点提供选择器(例如 XPath 中的 /text()),我希望找到一个创建自定义选择器的解决方案。

我知道如何以“非选择器”方式获取文本节点:

var textNode = $('#person').contents().filter(function(){
    return this.nodeType == 3;
}).text();

alert(textNode); // gives me "johndoe"

我如何将其转换为自定义选择器?以下显然不起作用,因为它总是返回完整元素,只要它的一部分是文本节点(正如@VinayC 在他的回答中解释的那样):

$.extend($.expr[':'],{
    getText: function(element){
        return $(element).contents().filter(function() {return this.nodeType == 3;}).text();
    }
});

alert($('#person:getText')); //returns the whole DIV element

见我的jsfiddle

也许使用 jQuery 自定义选择器无法做到这一点。这就是为什么我正在考虑“返回”到看起来更通用的 XPath。

谢谢你的帮助。

4

1 回答 1

2

您正在做的是创建一个 jquery 选择器,并且选择器函数应该返回布尔值以指示传递的节点是否匹配。因此,您当前的函数为“#person” div 返回一个“true”((实际返回值是 div 内的非空文本,因此被认为是 true),因此您得到 div 元素作为结果。

您可以尝试getText: function(node){ return node.nodeType == 3;},但这仅适用于 jquery 引擎通过选择器函数传递所有文档节点,包括文本节点(我不知道它是否这样做)。另一种方法是创建一个辅助函数而不是自定义选择器。

编辑:如何扩展 jquery 对象?例如,

$.fn.extend({
    getText: function() {
        return this.contents().filter(function() {return this.nodeType == 3;}).text();
    }
});

alert($('#person').getText());
于 2011-05-03T08:29:01.370 回答