如题。是否可能使用 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 ![]() 既然能指定到文字,那肯定能指定到选择器,把节点发出来看看,让大家帮你定位到元素 |
![]() | 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 ![]() 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); } |