如题。是否可能使用 JavaScript 选择网页里的指定文字?
有这个问题是因为需要选择某个节点的文字移动到其它节点显示。但是网页内容又是程序生成的,文字不在固定的节点里,节点元素也没有 id class 选择器。
1
kaiki 2020-05-03 16:17:49 +08:00
没有任何可以参考的变量怎么去选取啊?这个选择的规则是什么?
|
2
yafoo 2020-05-03 16:21:12 +08:00 via Android 1
既然能指定到文字,那肯定能指定到选择器,把节点发出来看看,让大家帮你定位到元素
|
3
LUREN OP @kaiki 文字所在的节点元素不固定,节点元素没有选择器,没有特征淹没在一大段内容里。。。
能够确定的是需要选择的文字是固定的,移动目标节点元素有 id 选择器,这种情况还有解么? |
4
ClericPy 2020-05-03 16:27:05 +08:00
看楼主的意思... 就是根据文字然后选中它, 这个选中是找到节点就行, 还是框选 createTextRange 那样?
PS: 能直接给例子或者描述完整需求么, 有可能一开始方向就歪了啊... |
5
kaiki 2020-05-03 16:29:13 +08:00
@LUREN 循环整个页面,处理这段文字,找到有特征的部分,用正则找出来,原来找到的部分该怎么处理怎么处理,新抓出来的这一段,该放哪放哪,这样可行吗?
|
6
ClericPy 2020-05-03 16:33:49 +08:00
听起来像 jQuery 的 contains...
|
7
imn1 2020-05-03 16:36:22 +08:00 1
css 选择器没有内容相关的,其实 css1/2 有,不知为何 css3 取消了
建议用 javascript 调用 xpath 的 text()搜索节点 另一个思路是不需要移动节点,把文字复制 /移动过去,让原节点不可见、不占位也可以 |
8
xiangyuecn 2020-05-03 16:45:50 +08:00
这是一个高级主题哦,要收费的。。虽然完成整个功能涉及的知识不多,但深度够深了😂
我也不会写,吹水,目测逃不过: 从 body 节点开始递归遍历所有节点,发现 text node 就判断一下是否包含特定文本,然后反过来确认包含此 text node 的上级 node 是符合需求的节点,然后全部找到,下一步脱裤子搞事 |
9
LUREN OP |
10
Arrowing 2020-05-03 16:57:18 +08:00
可以。
1 、遍历所有 body 下所有的含文字的节点( div 、span 、p 等); 2 、筛选出 innerHTML 包含你指定文字的节点; 3 、使用 window.getSelection 和 addRange 来 选中文字。 ```javascript function selectText(text) { let nodes = document.querySelectorAll('body *') let textNode let textStartIndex for (let i = 0, len = nodes.length; i < len; i++) { textStartIndex = nodes[i].innerHTML.indexOf(text) if (textStartIndex > -1) { if (nodes[i].children.length === 0) { textNode = nodes[i] break // 找到即返回 } } } if (textNode) { let range = document.createRange() // range.selectNode(textNode) range.setStart(textNode.firstChild, textStartIndex) range.setEnd(textNode.firstChild, textStartIndex + text.length) let selection = window.getSelection() selection.removeAllRanges() selection.addRange(range) } } selectText('指定文字') // 当前 V2EX 页面执行 ``` * 以上代码仅用于作为示例代码,并没有做边界测试,浏览器兼容,性能优化。 |
11
vangkinva 2020-05-03 16:58:01 +08:00
把 html 节点和内容都当文本,然后通过文字找到他在文本中的位置,通过向上比对找到它的节点名称,然后就找到他的节点了?
|
12
8qwe24657913 2020-05-03 17:01:19 +08:00
用 xpath 啊
```javascript const result = document.evaluate("//text()[contains(string(), '这里填文字内容')]", document.body, null, XPathResult.ANY_TYPE, null) let textNode while (textNode = result.iterateNext()) console.log(textNode) ``` |
13
ClericPy 2020-05-03 17:02:14 +08:00
我就感觉一开始需求就解读有问题...
这种情况先把 DemoA 的数据结构化成 map, 然后再迭代 DemoB, 从 map 里取 Google 什么的, 取到就塞 |
14
xiangyuecn 2020-05-03 17:05:38 +08:00
#9 你这个 demo 倒是简单了,也太工整了吧,怎么会没有特征?一次简单的遍历全部找到需要的内容节点
document.querySelector("#demoBoxA").querySelectorAll(".row").forEach(function(v){ if(/Google|Huawei|BlackBerry/i.test(v.querySelector(".col-md-6").innerText)){//text node 内容匹配检测 document.querySelector("#demoBoxB").appendChild(v) //下一步脱裤子搞事的事情自己写 } }) |
15
LUREN OP |
16
rabbbit 2020-05-03 20:38:15 +08:00
const rowEls = Array.from(document.querySelectorAll("#demoBoxA .row"));
rowEls.sort((a, b) => a.firstElementChild.innerText.localeCompare(b.firstElementChild.innerText)); const boxB = document.querySelector("#demoBoxB"); boxB.innerHTML = ""; for (let el of rowEls) { boxB.appendChild(el); } |