基于 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');
""