JavaScript:删除 HTML 标签、修改标签/文本以及重新插入标签

2024-03-18

我正在尝试找到一种方法来删除 HTML 文档中的所有标签,存储它们的位置,修改剩余的文本,然后将标签重新插入它们所属的位置。

关键点

  • I need to insert the tags back in again later, thus I need to store the location of each tag
    • 因此,建议使用 DOMParserhere https://stackoverflow.com/questions/822452/strip-html-from-text-javascript/47140708#47140708不管用
  • 这将在外部网站上完成,而不是我自己的网站
  • The regex suggested here https://stackoverflow.com/a/822464/3006096 (/<(?:.|\n)*?>/gm) will work, but it also falsely captures < or > included the html
    • 例子:https://regexr.com/3npfv https://regexr.com/3npfv
  • 看来这有效:https://regexr.com/3npgn https://regexr.com/3npgn (/<[^<|>]*>/g),但我读到使用正则表达式并不是解析 html 的好方法。有没有失败的情况?

完整代码:

function foo() {
    var elementHtml = document.body.innerHTML;
    var tags = [];
    var tagLocations = [];
    //var htmlTagRegEx =/<{1}\/{0,1}\w+>{1}/;
    var htmlTagRegEx =/<[^<]*>/;

    //Strip the tags from the elementHtml and keep track of them
    var htmlTag;
    while (htmlTag = elementHtml.match(htmlTagRegEx)) {
        console.log('htmlTag: ', htmlTag);
        tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
        tags[tags.length] = htmlTag;
        elementHtml = elementHtml.replace(htmlTag, '');
    }
}

EDIT

为了避免混淆,以下是我想要完成的任务的详细说明:

在整个(外部)网站(不包括标签)的文本中搜索字符串,然后更改这些实例的样式(例如颜色)(如果找到)。

这是我的尝试:

    function highlightInElement(elementId, text) {
        var elementHtml = document.body.innerHTML;
        var tags = [];
        var tagLocations = [];
        //var htmlTagRegEx =/<{1}\/{0,1}\w+>{1}/;
        var htmlTagRegEx =/<[^<]*>/;
        //Strip the tags from the elementHtml and keep track of them
        var htmlTag;
        while (htmlTag = elementHtml.match(htmlTagRegEx)) {
            //console.log('htmlTag: ', htmlTag);
            tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
            tags[tags.length] = htmlTag;
            elementHtml = elementHtml.replace(htmlTag, '');
        }
        console.log('elementHtml: ', elementHtml);

        //Search for the text in the stripped html
        var textLocation = elementHtml.search(text);
        if (textLocation) {
            //Add the highlight
            var highlightHTMLStart = '<span class="highlight">';
            var highlightHTMLEnd = '</span>';
            elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);

            //plug back in the HTML tags
            var textEndLocation = textLocation + text.length;
            for (let i = tagLocations.length - 1; i >= 0; i--) {
                var location = tagLocations[i];
                if (location > textEndLocation) {
                    location += highlightHTMLStart.length + highlightHTMLEnd.length;
                } else if (location > textLocation) {
                    location += highlightHTMLStart.length;
                }
                elementHtml = elementHtml.substring(0, location) + tags[i] + elementHtml.substring(location);
            }
        }

        //Update the html of the element
        document.body.innerHTML = elementHtml;
    }

    highlightInElement(document.documentElement, fooInputTxt.value);

为了避免混淆,下面详细解释了我想要完成的任务:在整个(外部)网站(不包括标签)的文本中搜索字符串,然后更改这些实例的样式(例如颜色)(如果找到) 。

那么这正是你应该做的:)

首先,构建一个递归函数来遍历 DOM 并获取所有文本节点:

function findTextNodes(node, ret) {
    var c = node.childNodes, i, l = c.length;
    for( i=0; i<l; i++) {
        switch(c[i].nodeType) {
            case 1: // element node
                findTextNodes(c[i], ret);
                break;
            case 3: // text node
                ret.push(c[i]);
                break;
        }
    }
}
var textNodes = [];
findTextNodes(document.body, textNodes);

现在您已经拥有了文档中所有文本节点的数组,您可以开始在它们中搜索您的目标。

function searchTextNodes(nodes, search) {
    var results = [], l = nodes.length, i,
        regex = new RegExp(search,'i'), match,
        span;
    for( i=0; i<l; i++) {
        while( (match = nodes[i].nodeValue.search(regex)) > -1) {
            nodes[i] = nodes[i].splitText(match);
            span = document.createElement('span');
            span.classList.add('highlight');
            nodes[i].parentNode.insertBefore(span, nodes[i]);
            nodes[i].splitText(search.length);
            span.appendChild(nodes[i]);
            nodes[i] = span.nextSibling;
        }
    }
}
searchTextNodes(textNodes, fooInputTxt.value);

而且……就是这样!为了获得额外的积分,以下是“撤消”搜索的方法:

function undoSearch(root) {
    var nodes = root.querySelectorAll("span.highlight"),
        l = nodes.length, i;
    for( i=0; i<l; i++) {
        nodes[i].parentNode.replaceChild(nodes[i].firstChild, nodes[i]);
    }
    root.normalize();
}
undoSearch(document.body);

JSFiddle 上的演示 https://jsfiddle.net/35L5seL9/1/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript:删除 HTML 标签、修改标签/文本以及重新插入标签 的相关文章

  • 使用 Charts.js 禁用动画

    我在使用 Charts js 关闭动画时遇到一些问题 这是我的代码 var pieData value 30 color F38630 value 50 color E0E4CC value 100 color 69D2E7 var myP
  • 如何更改点击事件上的引导插入符指向方向

    我正在使用 2 3 2 引导程序 因为当我单击菜单按钮时 我可以更改插入符号图标的位置 我需要当我单击图标插入符号向上时 当您单击另一个项目时 插入符号返回到初始状态 这怎么可能 导航代码 div div class container d
  • 将其作为参数传递给 addEventListener()

    我想添加change一组复选框的事件 我如何访问this在我的事件函数中 这样当我执行事件时我可以访问复选框的值 这是我当前的代码 var checkboxes document getElementsByClassName cb Arra
  • 更改 3 列显示的比例:表格/表格单元格

    我有这个简单的设置 container display table width 70 text align center div border 1px solid 336 column display table cell div clas
  • 强制执行 show.bind

    我有一个包含数据的表 当从另一个视图触发事件时 我希望视图检查 show bind 语句 问题是该事件没有更改当前视图中的任何数据 foo html tr p canBeRemoved p tr 我正在使用 EventAggregator
  • 将 javascript 放在 header 之外有多糟糕?

    这个问题几乎已经说明了一切 我开始添加一些功能到我的周末项目 http www my clock net 对于我和几个朋友来说 这是一个小应用程序 因为我们是交换生 所以它对我们来说有点有用 但事情是这样的 我在 php 中执行此操作并使用
  • 从对象获取数据 - 我看到数据但无法保存它们

    正如你所看到的 我是新来的 我确实尝试过搜索 但没有找到解决我问题的方法 所以这是我的问题 如果我这样做 console log grid data kendoGrid data 这在控制台中显示如下 所以我明白这一点 有一个数组和一个带有
  • 无法提取 Typescript 中的对象值

    我一直在尝试将 JavaScript Web 表单转换为 Typescript 但无法弄清楚如何处理以下内容 在 JavaScript 中有效 let fieldValues JSON parse cookieData let keys O
  • Facebook 登录无法在移动浏览器中使用

    我使用 react facebook login 在我的网站中实现了 facebook 登录module https github com keppelen react facebook login 我在 ComponentDidMount
  • Javascript“命名空间”和 jQuery AJAX

    我正在使用此处列出的建议 http www odetocode com articles 473 aspx http www odetocode com articles 473 aspx 使用模拟的JavaScript AJAX网络聊天系
  • 使用 jQuery 更改 SVG 元素的“xlink:href”属性

    我正在尝试使用单击事件更改 xlink href 属性 到目前为止它部分有效 这就是我正在做的 HTML a href class ui btn ui corner all ui shadow editIcon style text ali
  • IE 上具有最小宽度的内联跨度

    Hi我有 3 个SPAN那一定是inline并且有和一个min width 显然在 IE 上 SPAN不能有一个min width 我尝试使用DIV但当我把它放在inline the min width是忽略 CSS span displa
  • 根据数据更改图例颜色高图表

    我可以根据数据动态设置列的颜色 但无法弄清楚如何更改图例中的颜色 请注意 jsfiddle 最新的条形图是绿色的 但图例是蓝色的 有没有办法改变列颜色也会改变图例颜色 这是我用于列颜色的代码 jsfiddle http jsfiddle n
  • 单击时突出显示文本(javascript jquery html)

    当您在所有浏览器中双击某个单词时 它们会自动突出显示单击下的单词 但是否有可能找到一种方法exact单击一下就会发生同样的事情吗 我想这涉及到的事情可能是 TextRange 的东西 对所有段落 或整个正文或 div 的 onclick 做
  • 调用不带括号的 javascript 函数

    以下 renderChat 函数用于将消息和图像渲染到聊天板上 该函数内部还有另一个函数 var onComplete function 它完成创建列表元素并将其附加到聊天列表的所有工作 onComplete函数之后就只有这三行代码 img
  • 用于图形操作的 Javascript 库

    有没有建议的 javascript 替代 pythonpygraph http code google com p python graph or NetworkX http networkx lanl gov 应该注意的是 可视化不是必需
  • 按钮导致页面重新加载

    我在我的页面上使用 html 和 jquery 在我的 html 中 我有一个按钮 单击该按钮将触发一个功能 当页面加载时 我调用文档准备中的主函数 这是我的代码 div div
  • Antd select 元素:如何禁用输入?

    我正在尝试使用模式 multiple 的选择元素 我希望禁用输入 这意味着用户只能在现有选项之间进行选择 而不能输入文本 我该怎么做呢 我的元素 import Select from antd import antd dist antd c
  • 如何从 HTML 中的列数据而不是行数据创建表格?

    根据这篇文章W3学校 http www w3schools com html html tables asp 可以像这样在 HTML 中创建一个基本表格 table border 1 tr td row 1 cell 1 td td row
  • Bootstrap - 为反向行模式创建移动自适应

    我想用 Bootstrap 创建一个反向效果 第一行 左边是文字 右边是图像 第二行 左边是图片 右边是文字 第三行 左边是文字 右边是图片 第四行 左边是图片 右边是文字 而且这种情况一直持续下去 它在大型设备上看起来非常漂亮 但当它在设

随机推荐

  • postgresql 多个子查询

    我手头有一项任务 要求我返回一个学生的详细信息 该学生参加了一位姓霍夫曼的老师所教的课程 但我陷入了困境 SELECT FROM Public Class WHERE tid SELECT tid FROM Public Tutor WHE
  • 在 MVC Web 应用程序中访问 profile.newproperty

    我最近问了这个问题如何保留匿名用户选择 例如 主题选择 https stackoverflow com questions 11706349 how to persist anon user selection ex theme selec
  • 将解析信息添加到 Robolectric 包管理器

    这个问题与我想做的非常相似 如何使用 Robolectric 隐藏 PackageManager https stackoverflow com questions 12902777 how can i shadow the package
  • $.when 不等待 Ajax 请求完成

    我想首先使用 Backbone js 渲染一个视图 该视图显示从服务器拉取的文章 然后 我想将其标记为 已见 并将未见消息的计数返回给路由器 因为它需要可供其他视图使用 所以在我的路由器中 我有 getArticle function id
  • 使用javascript在IE中设置cookie

    document cookie cookiename cookievalue 过期 星期一 12Jun2015 00 00 00 路径 我在 Internet Explorer 10 上运行此脚本 但它不在 2 个 IE 选项卡之间共享 c
  • Unity 2D Trail 渲染器碰撞

    我制作 2D unity 游戏 但我面临着我的游戏所依赖的一个主要问题 我将一个轨迹渲染器组件附加到我的播放器上 我需要的是使渲染器成为一个碰撞器 充当网格碰撞器我只是不知道是否可以使碰撞器呈现 2D 轨迹渲染器的形状 我在谷歌上搜索过 但
  • 将 StackExchange.Redis 客户端与 Redis 集群结合使用

    如何告诉 StackExchange Redis v1 0 481 它即将连接到 Redis 集群 v3 2 6 如果重要的话 而不仅仅是独立 复制实例 例如 当我使用 redis cli 时 我必须传递 c 标志以使其具有集群感知能力 S
  • 尝试修复 tkinter GUI 冻结问题(使用线程)

    我有一个 Python 3 x 报告创建器 它的 I O 限制非常大 由于 SQL 而不是 Python 以至于主窗口将 锁定 minutes在创建报告时 所需要的只是能够在 GUI 锁定时使用标准窗口操作 移动 调整大小 最小化 关闭等
  • 使用 nbconvert 作为库运行预处理器

    我想使用预处理器运行 nbconvert 该预处理器会删除标有 skip 标签的单元格 我可以从命令行执行此操作 但是当我尝试在笔记本中使用 nbconvert API 时 我遇到了问题 一个例子 按照中的示例文档 https nbconv
  • 彩色打印页眉和页脚?

    我正在尝试在打印 JTable 时创建彩色页眉和页脚 具体来说 我正在查看 javax swing JTable 中的 getPrintable 但 MessageFormat 没有提供指定页眉或页脚颜色的选项 我该怎么做 澄清我有兴趣在打
  • c++11 union 包含带有虚函数的数据成员

    include
  • 回复然后继续使用 AWS Lambda/API Gateway? [复制]

    这个问题在这里已经有答案了 我目前有一个 Web 挂钩 正在调用 AWS API Gateway gt AWS Lambda 函数代理 我想让 Web 挂钩响应更快 并在继续在 Lambda 中处理的同时返回早期回复 我继续执行 Lambd
  • 在Java中解压缩GZip字符串

    我可以找到很多可以解压缩 GZip 文件的函数 但是如何解压缩 GZip 字符串呢 我正在尝试解析 HTTP 响应 其中响应正文是用 GZip 压缩的 但是 整个响应只是存储在字符串中 因此字符串的一部分包含二进制字符 我正在尝试使用 by
  • boost lib 构建配置变化

    我是 boost 新手 你能告诉我黑白有什么区别吗 boost 库的以下变体以及在哪种情况下我需要链接到哪一个 libboost unit test framework vc80 1 35 lib libboost unit test fr
  • 如何制作一个非常大的 Facebook 分享按钮?

    我想制作一个动态的 facebook 分享按钮 我当然可以在 facebook 页面上制作 但是 我想制作一个非常大的按钮 就像在这个网站上一样 http fullm com 这些 photos of an el salvador pris
  • 输入“有吗?”没有下标成员(使用 Firebase)

    每次我运行这行代码时它都不起作用 任何人都可以帮助我改变它吗 谢谢你的帮助 以下是我不断收到的错误 输入任意 没有下标成员 var ref FIRDatabaseReference var refHandle UInt var postDa
  • Postgres全文搜索:如何在多个字段中搜索多个单词?

    我第一次使用 Postgresql 我正在尝试在我的网站中创建一个搜索引擎 我有这张表 CREATE TABLE shop id SERIAL PRIMARY KEY name TEXT NOT NULL description TEXT
  • 如何在 O(1) 时间内找到二进制数中 1 的个数?

    我知道以前曾问过这个问题 但我正在查看列出的这个特定解决方案here https stackoverflow com a 8871435 1418853 int BitCount unsigned int u unsigned int uC
  • 实体框架:一个数据库,多个DbContext。这是一个坏主意吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 迄今为止我的印象是DbContext旨在代表您的数据库 因此 如果您的应用程序使用一个数据库 您只需要一个DbContext 然而 一些同事希望
  • JavaScript:删除 HTML 标签、修改标签/文本以及重新插入标签

    我正在尝试找到一种方法来删除 HTML 文档中的所有标签 存储它们的位置 修改剩余的文本 然后将标签重新插入它们所属的位置 关键点 I need to insert the tags back in again later thus I n