-
Notifications
You must be signed in to change notification settings - Fork 6
中文API文档
Xuanzi edited this page Feb 8, 2022
·
21 revisions
Visdom 用来解析html文档节点树,并可对节点树采用jquery类似的api来进行操作。API基本和jquery保持一致,除了函数命名在rust中采用短横杠分割(snake-case)的方式,代替了jquery使用的驼峰(camel-case)方式,另外在jquery中参数支持多种格式的API,在visdom中采用了拆分成一组API的形式。
由于其api与jquery基本类似,所以对于习惯使用jquery的同学非常容易上手。但注意visdom
并不提供也无法提供jquery中与渲染、事件等相关的API,因为这些属于浏览器的功能部分,visdom
并不能提供这样的环境。
此外,visdom
针对文本节点实现了选取texts(0)
、修改set_html()\set_text()
方法,所以用它来做网页内容的筛选抓取或者更改节点防止被抓取也是十分方便的。
Cargo.toml
main.rs
use visdom::Vis;
use visdom::types::BoxDynError;
fn main()-> Result<(), BoxDynError>{
let html = r##"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<nav id="header">
<ul>
<li>Hello,</li>
<li>Vis</li>
<li>Dom</li>
</ul>
</nav>
</body>
</html>
"##;
// load html
let root = Vis::load(html)?;
let lis = root.find("#header li");
let lis_text = lis.text();
println!("{}", lis_text);
// 将输出 "Hello,VisDom"
Ok(())
}
静态方法:load(html: &str) -> Result<NodeList, BoxDynError>
加载html文档字符串为NodeList元素集合,如果后续对集合的选择器操作中有selector参数错误,错误将不会被捕获,要想捕获错误,请使用`load_catch`方法。
静态方法:load_catch(html: &str, handle: Box<dyn Fn(BoxDynError)>) -> NodeList
加载html文档字符串为NodeList元素集合,同时设置错误处理方法`handle`,如果你希望在html解析错误、选择器方法中selector书写不正确的情况下能统一被处理,可以使用该方式加载。
静态方法:dom(ele: &BoxDynNode) -> NodeList
将一个ele元素转换为NodeList元素集合,主要用于在API中带回调方法参数的方法中,ele元素上自带了INodeTrait实现的方法<在mesdoc中可查看>,如果不需要做一些复杂的查找操作等,你将不需要使用该方法,该方法会复制ele节点。
示例:
// 接以上示例
let texts = lis.map(|_index, ele|{
let ele = Vis::dom(ele);
return String::from(ele.text());
});
// 则texts为Vec<String>, ["Hello,", "Vis", "Dom"]
// 没有被包装的ele元素具备的方法可以查看mesdoc接口方法
Trait Object | Trait | Inherit | 文档 |
---|---|---|---|
BoxDynNode | INodeTrait | None | INodeTrait Document |
BoxDynElement | IElementTrait | INodeTrait | IElementTrait Document |
BoxDynText | ITextTrait | INodeTrait | ITextTrait Document |
Box<dyn IDocumentTrait> | IDocumentTrait | None | IDocumentTrait Document |
集合 | 文档 |
---|---|
Elements | Elements Document |
Texts | Texts Document |
选择器方法 | 说明 | 备注 |
---|---|---|
除is_ 开头的方法,以下方法返回值也为Elements 元素集合 |
||
find (selector: &str) |
查找匹配选择器的子孙元素 | |
filter (selector: &str) |
筛选出匹配选择器的元素 | |
filter_by (|index: usize, ele: &BoxDynNode| -> bool) |
根据闭包方法返回的值,true则包含,false将被排除 | 对应filter方法参数为函数的形式 |
filter_in (node_list: &NodeList) |
在node_list中的元素将被包含,否则被排除 | 对应filter方法参数为集合的形式 |
not (selector: &str) |
排除匹配选择器的元素 | |
not_by (|index: usize, ele: &BoxDynNode| -> bool) |
根据闭包方法返回的值,true则被排除,false则包含 | 对应not方法参数为函数的形式 |
not_in (node_list: &NodeList) |
在node_list中的元素将被排除,否则包含 | 对应not方法参数为集合的形式 |
is (selector: &str)->bool |
判断是否有一个元素匹配选择器 | |
is_by (|index: usize, ele: &BoxDynNode| -> bool)->bool |
根据闭包方法返回的值,有任意一个为true则返回true | 对应is方法参数为函数的形式 |
is_in (node_list: &NodeList)->bool |
有任意一个元素包含在node_list中,则返回true | 对应is方法参数为集合的形式 |
is_all (selector: &str)->bool |
判断是否所有元素都匹配选择器 | 库额外提供方法 |
is_all_by (|index: usize, ele: &BoxDynNode| -> bool)->bool |
根据闭包方法返回的值,全部为true则返回true,否则false | is_all方法参数为函数的形式 |
is_all_in (node_list: &NodeList)->bool |
所有元素都包含在node_list中,则返回true,否则为false | is_all方法参数为集合的形式 |
has (selector: &str) |
筛选出子级元素中包含匹配选择器的元素 | |
has_in (node_list: &NodeList) |
筛选出有子级元素包含在node_list中的元素 | |
children (selector: &str) |
从子元素开始,查找匹配选择器的元素 | |
parent (selector: &str) |
从父元素开始,查找匹配选择器的元素 | |
parents (selector: &str) |
从父元素及祖先元素开始,查找匹配选择器的元素 | |
parents_until (selector: &str, filter: &str, contains: bool) |
从父元素向祖先元素一步步往上查找,遇到匹配到selector 的父元素或祖先元素时停止查找,当contains为true时,匹配到的元素也包含在查找到的元素集合内;当filter 参数不为空时,会使用filter 对所有查找到的元素进行筛选。 |
|
closest (selector: &str) |
从自身开始向父元素及祖先元素一步步向上查找,当找到匹配到的元素即停止查找,返回匹配到的第一个元素。 | |
siblings (selector: &str) |
从兄弟元素开始,查找匹配选择器的元素 | |
next (selector: &str) |
从后一个紧挨兄弟元素开始,查找匹配选择器的元素 | |
next_all (selector: &str) |
从后面所有兄弟元素开始,查找匹配选择器的元素 | |
next_until (selector: &str, filter: &str, contains: bool) |
从后面兄弟元素向后开始查找,遇到匹配selector 时停止查找,当contains为true时,匹配到的元素也包含在查找到的元素集合内;当filter 参数不为空时,会使用filter 对所有查找到的元素进行筛选。 |
|
prev (selector: &str) |
从前一个紧挨兄弟元素开始,查找匹配选择器的元素 | |
prev_all (selector: &str) |
从前面所有兄弟元素开始,查找匹配选择器的元素 | |
prev_until (selector: &str, filter: &str, contains: bool) |
从前面兄弟元素向前开始查找,遇到匹配selector 时停止查找,当contains为true时,匹配到的元素也包含在查找到的元素集合内;当filter 参数不为空时,会使用filter 对所有查找到的元素进行筛选。 |
|
eq (index: usize) |
获取元素列表中第 index 个 | |
first () |
获取元素集合的第一个元素,是eq(0) 的等价形式 |
|
last () |
获取元素集合的最后一个元素,是eq(length-1) 的等价形式 |
|
slice <T: RangeBounds>(range: T) |
获取某段范围内元素 | 如:slice(..3),表示前三个元素,slice(1..)表示第一个以后的所有元素 |
add (eles: Elements) |
将当前Self 集合中包含的元素和eles 参数集合中的元素合并出一个新的元素集合,注意它不会改变Self 自身,同时会获取eles 参数的所有权,eles不能再被使用 |
辅助方法 | 说明 | 备注 |
---|---|---|
length ()->usize |
返回元素集合长度 | |
is_empty ()->bool |
判断元素集合是否为空 | |
for_each (|index: usize, ele: &mut BoxDynNode| -> bool) |
对每个元素进行遍历,当返回值为false时停止遍历 | 如果你喜欢简短写法,使用 each 也是一样的 |
map <T>(|index: usize, ele: &BoxDynNode| -> Vec<T>) |
对每个元素进行遍历,返回回调方法返回值的集合 | |
document () |
当元素集合不为空集的时候,可以用来快速获取document文档节点,通常在执行Vis::load 后执行该操作 |
选择器 | 说明 | 备注 |
---|---|---|
* |
所有元素 | 元素选择器可参见 MDN css 选择器文档 |
#id |
id 选择器 | |
.class |
类选择器 | |
p |
标签名选择器 | |
[attr] |
含有{attr}的元素 | |
[attr=value] |
{attr}值为{value}的元素 | |
[attr*=value] |
{attr}包含{value}值的元素 | |
[attr|=value] |
{attr}包含{value}值或者{value}-的元素 | |
[attr~=value] |
{attr}包含{value}值,且值是以空格作为分隔的元素 | |
[attr^=value] |
{attr}以{value}值开头的元素 | |
[attr$=value] |
{attr}以{value}值结尾的元素 | |
[attr!=value] |
包含{attr},且值不为{value}的元素 | |
span > a |
子元素选择器 | 匹配父元素为 span 的 a 元素 |
span a |
子孙元素选择器 | 匹配 span 元素下的所有子孙 a 元素 |
span + a |
相邻元素选择器 | 匹配 span 后面紧邻的兄弟 a 元素 |
span ~ a |
后面兄弟元素选择器 | 匹配 span 后面所有的兄弟 a 元素 |
span.a |
多条件筛选选择器 | 匹配 span 且 class 名包含 a 的元素 |
:empty |
没有子元素的元素 | |
:root |
返回文档的html根元素 | 以下都为伪类选择器 |
:first-child |
第一个子元素 | |
:last-child |
最后一个子元素 | |
:only-child |
唯一子元素 | |
:nth-child(nth) |
nth 表示为 a'n + b',a'和 b'为整数<零及正负>,n 从 0 开始计数,和为 1 则表示第一个子元素,最终将获取所有符合该数列值的子元素 | nth 形式的选择器都支持 odd 和 even 关键字 |
:nth-last-child(nth) |
同上,但从最后一个子元素开始计数算作第一个子元素 | |
:first-of-type |
子元素中第一个出现的标签元素<按标签名> | |
:last-of-type |
子元素中最后一个出现的标签元素<按标签名> | |
:only-of-type |
子元素中只出现一次的标签元素<按标签名> | |
:nth-of-type(nth) |
子元素中标签<按标签名>出现顺序符合数列值的元素 | |
:nth-last-of-type(nth) |
同上,但出现顺序从最后一个元素往前数 | |
:not(selector) |
匹配不符合 selector 选择器的元素 | |
:checked |
表单选中元素,针对select内的option 及 input[type="radio"],input[type="checkbox"]元素 | |
:header |
所有标题元素,h1,h2,h3,h4,h5,h6 的别名 | |
:input |
所有表单元素,input,select,textarea,button 的别名 | |
:submit |
表单提交按钮,input[type="submit"],button[type="submit"] 的别名 |
属性方法 | 说明 | 备注 |
---|---|---|
没有标明返回值的,均返回Elements 元素集合自身,可以进一步链式调用 |
||
attr (attr_name: &str) -> Option<IAttrValue> |
获取属性 | 值为 Option<IAttrValue > 枚举类型,IAttrValue 自身具备is_true() ,is_str(&str) 及to_list() 等方法 |
set_attr (attr_name: &str, value: Option<&str>) |
设置属性值,当 value 为 None 时,表示设置布尔 true,没有字符串属性值 | |
has_attr (attr_name: &str, value: Option<&str>) |
判断节点上是否包含某个属性名为attr_name 的属性 |
|
remove_attr (attr_name: &str) |
删除属性 | |
has_class (class_name: &str) -> bool |
判断元素中是否至少有一个元素包含 class 类名,多个 class 用空格隔开 | |
add_class (class_name: &str) |
增加 class 类名,多个 class 用空格隔开 | |
remove_class (class_name: &str) |
删除 class 类名 | |
toggle_class (class_name: &str) |
切换 class 类名,存在则删除,不存在则添加 |
文本方法 | 说明 | 备注 |
---|---|---|
text ()->&str |
获取所有元素的文本内容,实体将会自动 decode | |
set_text (content: &str) |
设置元素的内容为 content 文本<自动 encode 实体> | |
val ()->IFormValue |
获取select选中option,option,input,textarea等的值 | |
html ()->&str |
获取第一个元素的 html 文档内容 | |
set_html (content: &str) |
设置元素的子节点为 content 解析后的子节点 | |
outer_html ()->&str |
获取第一个元素的 html 文档内容,包含节点本身 | |
texts (limit_depth: u32)-> Texts |
获取元素的文本内容,limit_depth设置允许递归层次,0为不限制 |
dom 节点操作方法 | 说明 | 备注 |
---|---|---|
append (nodes: &mut NodeList) |
将所有节点插入节点子元素最后 | |
append_to (nodes: &mut NodeList) |
同上,但交换参数与调用者 | |
prepend (nodes: &mut NodeList) |
将所有节点插入节点子元素开始 | |
prepend_to (nodes: &mut NodeList) |
同上,但交换参数与调用者 | |
insert_after (nodes: &mut NodeList) |
将所有节点插入该元素之后 | |
after (nodes: &mut NodeList) |
同上,但交换参数与调用者 | |
insert_before (nodes: &mut NodeList) |
将所有节点插入该元素之前 | |
before (nodes: &mut NodeList) |
同上,但交换参数与调用者 | |
remove () |
删除节点,删除后持有的变量将不能再使用 | |
empty () |
清空节点内所有子元素 |
let html = r##"
<div class="second-child"></div>
<div id="container">
<div class="first-child"></div>
</div>
"##;
let root = Vis::load(html)?;
let mut container = root.find("#container");
let mut second_child = root.find(".second_child");
// 将child元素插入到container子元素最后
container.append(&mut second_child);
// 代码将变成
/*
<div id="container">
<div class="first-child"></div>
<div class="second-child"></div>
</div>
*/
let mut third_child = Vis::load(r##"<div class="third-child"></div>"##)?;
container.append(&mut third_child);
// 代码将变成
/*
<div id="container">
<div class="first-child"></div>
<div class="second-child"></div>
<div class="third-child"></div>
</div>
*/
- Html解析器:https://github.com/fefit/rphtml
- Html实体编解码:https://github.com/fefit/htmlentity
如果您有好的意见、想法、或者使用中遇到bug问题等,欢迎提 Issue 给我们.