能否使用 Javascript 选中网页里的指定文字? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
LUREN
V2EX    Javascript

能否使用 Javascript 选中网页里的指定文字?

  •  
  •   LUREN 2020-05-03 16:13:28 +08:00 3305 次点击
    这是一个创建于 1997 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题。是否可能使用 Javascript 选择网页里的指定文字?

    有这个问题是因为需要选择某个节点的文字移动到其它节点显示。但是网页内容又是程序生成的,文字不在固定的节点里,节点元素也没有 id class 选择器。

    kaiki
        1
    kaiki  
       2020-05-03 16:17:49 +08:00
    没有任何可以参考的变量怎么去选取啊?这个选择的规则是什么?
    yafoo
        2
    yafoo  
       2020-05-03 16:21:12 +08:00 via Android   1
    既然能指定到文字,那肯定能指定到选择器,把节点发出来看看,让大家帮你定位到元素
    LUREN
        3
    LUREN  
    OP
       2020-05-03 16:24:40 +08:00
    @kaiki 文字所在的节点元素不固定,节点元素没有选择器,没有特征淹没在一大段内容里。。。
    能够确定的是需要选择的文字是固定的,移动目标节点元素有 id 选择器,这种情况还有解么?
    ClericPy
        4
    ClericPy  
       2020-05-03 16:27:05 +08:00
    看楼主的意思... 就是根据文字然后选中它, 这个选中是找到节点就行, 还是框选 createTextRange 那样?

    PS: 能直接给例子或者描述完整需求么, 有可能一开始方向就歪了啊...
    kaiki
        5
    kaiki  
       2020-05-03 16:29:13 +08:00
    @LUREN 循环整个页面,处理这段文字,找到有特征的部分,用正则找出来,原来找到的部分该怎么处理怎么处理,新抓出来的这一段,该放哪放哪,这样可行吗?
    ClericPy
        6
    ClericPy  
       2020-05-03 16:33:49 +08:00
    听起来像 jQuery 的 contains...
    imn1
        7
    imn1  
       2020-05-03 16:36:22 +08:00   1
    css 选择器没有内容相关的,其实 css1/2 有,不知为何 css3 取消了
    建议用 Javascript 调用 xpath 的 text()搜索节点

    另一个思路是不需要移动节点,把文字复制 /移动过去,让原节点不可见、不占位也可以
    xiangyuecn
        8
    xiangyuecn  
       2020-05-03 16:45:50 +08:00
    这是一个高级主题哦,要收费的。。虽然完成整个功能涉及的知识不多,但深度够深了

    我也不会写,吹水,目测逃不过:

    从 body 节点开始递归遍历所有节点,发现 text node 就判断一下是否包含特定文本,然后反过来确认包含此 text node 的上级 node 是符合需求的节点,然后全部找到,下一步脱裤子搞事
    LUREN
        9
    LUREN  
    OP
       2020-05-03 16:46:27 +08:00
    Arrowing
        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 页面执行
    ```

    * 以上代码仅用于作为示例代码,并没有做边界测试,浏览器兼容,性能优化。
    vangkinva
        11
    vangkinva  
       2020-05-03 16:58:01 +08:00
    把 html 节点和内容都当文本,然后通过文字找到他在文本中的位置,通过向上比对找到它的节点名称,然后就找到他的节点了?
    8qwe24657913
        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)
    ```
    ClericPy
        13
    ClericPy  
       2020-05-03 17:02:14 +08:00
    我就感觉一开始需求就解读有问题...

    这种情况先把 DemoA 的数据结构化成 map, 然后再迭代 DemoB, 从 map 里取 Google 什么的, 取到就塞
    xiangyuecn
        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) //下一步脱裤子搞事的事情自己写
    }
    })
    LUREN
        15
    LUREN  
    OP
       2020-05-03 20:04:27 +08:00
    @Arrowing
    @8qwe24657913
    @ClericPy
    @xiangyuecn 感谢大佬们提供的解思路,我去试试。
    rabbbit
        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);
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3509 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 54ms UTC 04:33 PVG 12:33 LAX 21:33 JFK 00:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86