jQuery文本节点的自定义选择器 [英] jQuery custom selector for text nodes

查看:126
本文介绍了jQuery文本节点的自定义选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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


添加新网站:



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



路径: _ __ _ __ _ __ _ __ / strong>(例如,.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 ...< / span>
< / div>由于jQuery不提供文本节点的选择器(如XPath中的/ text()),因此,我希望找到一个创建自定义选择器的解决方案。



我知道如何获得文本节点的非选择器方式:

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

alert(textNode); //给我johndoe

如何将它转换为自定义选择器?下面显然不工作,因为它总是返回完整的元素,只要它的一部分是一个文本节点(如@VinayC解释在他的答案):

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

alert($('#person:getText')); //返回整个DIV元素

查看我的 jsfiddle



也许使用jQuery自定义选择器不可能做到这一点。这就是为什么我想'回到'XPath看起来更多样化。



感谢您的帮助。

解决方案

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



你可以尝试 getText:function(node){return node.nodeType == 3;} 所有文档节点包括通过选择器函数的文本节点(我不知道它是否有)。Alternate是创建一个辅助函数,而不是自定义选择器。



如何扩展jquery对象?例如,

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

alert($('#person')。getText());


I would like to extract text from a DOM element using a jQuery custom selector. It should only select the text node without it's tagged siblings (much like /text() in XPath).

Background: I am working on a Firefox extension, that extracts some specific information (e.g. a username) on very different websites. Now I want my users to be able to dynamically add path definitions for new websites over a form as simple as possible:

Add new Website:

URL: ________________ (e.g. "http://stackoverflow.com/questions/")

Path: ________________ (e.g. ".user-details>a:eq(0)" for the name of the user asking a question)

On stackoverflow for instance, $(path).text() will return the username as text. But on some other sites the username is available only as text node with tagged siblings, as in this example:

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

Since jQuery doesn't provide a selector for text nodes (like /text() in XPath), I was hoping to find a solution creating a custom selector.

I know how to get the text node the 'non-selector' way:

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

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

How would I translate this into a custom selector? The following obviously doesn't work, since it always returns the complete element as soon as one part of it is a text node (as @VinayC explains in his answer):

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

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

See my jsfiddle

Maybe it's not possible to do this with jQuery custom selectors. That's why I'm thinking about going 'back' to XPath which seems more versatile.

Thanks for your help.

解决方案

What you are doing is to create a jquery selector and the selector function is supposed to return boolean to indicate if the passed node has matched or not. So your current function returns a "true" for "#person" div ((actual return value is text within div which is non-empty and hence considered as true) and hence you get the div element as result.

You may try getText: function(node){ return node.nodeType == 3;} but this will work only jquery engine passes all document nodes including text nodes via selector functions (I am unaware if it does or does not). Alternate is to create an helper function instead of custom selector.

EDIT: how about extending jquery object? For example,

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

alert($('#person').getText());

这篇关于jQuery文本节点的自定义选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆