基于 dom.el,目前只支持这些选择器和组合子:
| Syntax |
Example |
Example description |
.class |
.intro |
Select all elements with class="intro"
|
.class1.class2 |
.name1.name2 |
Select all elements with both name1 and name2 set within its class attribute |
#id |
#firstname |
Select all elements with id="firstname"
|
tag |
p |
Select all <p> elements |
[attr=fullstring] |
[target=_blank] |
Select all elements with target="_blank"
|
| `[attr |
=prefix]` |
`[lang |
[attr~=word] |
[title~=flower] |
Select all elements with title attribute containing the word “flower” |
[attr^=prefix] |
a[href^=https] |
Select every <a> element whose href attribute value begins with “https” |
[attr*=substring] |
a[href*=example] |
Select every <a> element whose href attribute value contains “example” |
[attr$=prefix] |
a[href$=.pdf] |
Select every <a> element whose href attribute value ends with “https” |
ancestor descendant |
div p |
Select all <p> elements inside <div> elements |
parent > child |
div > p |
Select all <p> elements where the parent is a <div> element |
prev + adjacent |
div + p |
Select all <p> elements that are placed immegiately after <div> elements |
prev ~ siblings |
p ~ ul |
Select every <ul> element that are placed by a <p> element |
parent < child |
div < p |
Select all <div> elements which contains at least one <p> element |
用法:
(dom-select dom "selector string")
类似的项目:
-
elquery 输出的是自定义结构,后续处理无法利用内置的
dom- 函数。而且在我试用的过程中,发现有时选不到元素。
-
doom.el JS 风格的接口,项目已停更并删库了,这里有个 fork。
2 个赞
看起来相当完善啊,为啥我没有早发现它。
完善度比较(
表示得分):
| Name |
esxml-query |
dom-select |
Syntax |
| Namespaces |
No |
No |
foo |
| Commas |
Yes🚩 |
No |
foo,bar |
| Descendant combinator |
Yes |
Yes |
foo bar |
| Child combinator |
Yes |
Yes |
foo>bar |
| Parent combinator |
No |
Yes🚩 |
foo<bar |
| Adjacent sibling combinator |
No |
Yes🚩 |
foo+bar |
| General sibling combinator |
No |
Yes🚩 |
foo~bar |
| Universal selector |
Yes🚩 |
No |
* |
| Type selector |
Yes |
Yes |
tag |
| ID selector |
Yes |
Yes |
#foo |
| Class selector |
Yes |
Yes |
.foo |
| Attribute selector |
Yes |
Yes |
[foo] |
| Exact match attribute selector |
Yes |
Yes |
[foo=bar] |
| Prefix match attribute selector |
Yes |
Yes |
[foo^=bar] |
| Suffix match attribute selector |
Yes |
Yes |
[foo$=bar] |
| Substring match attribute selector |
Yes |
Yes |
[foo*=bar] |
| Include match attribute selector |
Yes |
Yes |
[foo~=bar] |
| Dash match attribute selector |
Yes |
Yes |
[foo |
| Attribute selector modifiers |
No |
No |
[foo=bar i] |
| Pseudo elements |
No |
No |
::foo |
| Pseudo classes |
No |
No |
:foo |
(其中 Parent combinator 并非标准实现,是借用 jQuery :has 选择器的想法。)
这么一比较,让我感觉到少许安慰:暂时看起来没白写。
另外,我对它 `[foo]` 的实现有疑问,例如以下情况就选不到元素了:
(with-temp-buffer
(insert "<p disabled>disabled element</p>")
(let ((dom (libxml-parse-xml-region (point-min) (point-max))))
(esxml-query "[disabled]" dom)))
;; => nil
因为 libxml-parse-xml-region 直接把没有值的 attribute 删掉了。这也是我纠结了很久,最后决定放弃实现 [attr] 的原因。
1 个赞
用 libxml-parse-html-region 是正常的:
(with-temp-buffer
(insert "<p disabled>disabled element</p>")
(libxml-parse-html-region (point-min) (point-max)))
;; => (html nil (body nil (p ((disabled . "disabled")) "disabled element")))
(with-temp-buffer
(insert "<p disabled>disabled element</p>")
(libxml-parse-xml-region (point-min) (point-max)))
;; => nil
只有 disabled readonly 等内置属性(更多见 html-tag-alist)有效,自定义属性无效:
(with-temp-buffer
(insert "<p foo></p>")
(libxml-parse-html-region (point-min) (point-max)))
;; => (html nil (body nil (p nil)))
没有值返回空字符不是更好吗?
(with-temp-buffer
(insert "<p foo=\"\"></p>")
(libxml-parse-html-region (point-min) (point-max)))
;; => (html nil (body nil (p ((foo . "")))))
在 Google Chrome 的控制台读取 readonly 得到的就是空字符:
> $$('input')[0].getAttribute('readonly');
""