天道酬勤,学无止境

How to wrap part of all text_node nodeValue in an html element?

问题

我正在遍历 html 文档中的所有文本节点,以便用特定跨度包围一些单词。

更改nodeValue不允许我插入 html。 span被转义为以纯文本显示,我不希望这样。

这是我到目前为止所拥有的:

 var elements = document.getElementsByTagName('*'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; for (var j = 0; j < element.childNodes.length; j++) { var node = element.childNodes[j]; if (node.nodeType === Node.TEXT_NODE) { node.nodeValue = node.nodeValue.replace(/Questions/, "<span>Questions</span>"); } } }
 <p>Questions1</p> <p>Questions 2</p> <p>Questions 3</p> <p>Questions 4</p>
回答1

我认为你需要递归所有的 DOM 和每场比赛......看看这里:

 function replacer(node, parent) { var r = /Questions/g; var result = r.exec(node.nodeValue); if(!result) { return; } var newNode = this.createElement('span'); newNode.innerHTML = node .nodeValue .replace(r, '<span class="replaced">$&</span>') ; parent.replaceChild(newNode, node); } document.addEventListener('DOMContentLoaded', () => { function textNodesIterator(e, cb) { if (e.childNodes.length) { return Array .prototype .forEach .call(e.childNodes, i => textNodesIterator(i, cb)) ; } if (e.nodeType == Node.TEXT_NODE && e.nodeValue) { cb.call(document, e, e.parentNode); } } document .getElementById('highlight') .onclick = () => textNodesIterator( document.body, replacer ); });
 .replaced {background: yellow; } .replaced .replaced {background: lightseagreen; } .replaced .replaced .replaced {background: lightcoral; }
 <button id="highlight">Highlight</button> <hr> <p>Questions1</p> <p>Questions 2</p> <p>Questions 3</p> <p>Questions 4</p> <p>Questions 5 Questions 6</p> <div> <h1>Nesting</h1> Questions <strong>Questions 4</strong> <div> Questions <strong>Questions 4</strong></div> <div> Questions <strong>Questions 4</strong> <div> Questions <strong>Questions 4</strong></div> </div> </div>
回答2

最后,我可以在不添加额外标记的情况下做到这一点,除了所需的跨度:

更新

jsFiddle

 var elements = document.body.getElementsByTagName('*');; for (var i = 0; i < elements.length; i++) { var element = elements[i]; for (var j = 0; j < element.childNodes.length; j++) { var node = element.childNodes[j], par = node.parentElement; // as well as checking the nodeType as text, we make sure the // parent element doesn't have the class "foo", so that we only // wrap the keyword once, instead of being in a loop to infinity if (node.nodeType === Node.TEXT_NODE && !par.classList.contains('foo')) { updateText(node, par); } } } function updateText(el, par) { var nv = el.nodeValue, txt = nv.replace(/Questions/g, '<span class="foo">Questions</span> '); // replace the whole old text node with the new modified one // and inject it as parent HTML par.innerHTML = par.innerHTML.replace(nv, txt); }
 .foo {color: white; background-color: green; padding: 5px;}
 <div id="wrapper"> this is test looking for the the word Questions. <br> <div id="test"> <p>Lorem ipsum dolor Questions sit amet, <strong>consectetur</strong> adipisicing elit.</p> <p>Questions 1</p> <p>Questions 2</p> <p>Questions 3</p> <p>Questions 4</p> </div> <div>Lorem ipsum dolor sit amet, Questions consectetur adipisicing elit. Ipsa sed Questions ratione dolorem at repellendus animi eveniet similique repellat, sequi rem numquam debitis sit reprehenderit laborum dicta omnis iure quidem atque?</div> </div>
回答3

看到评论,不要使用它,因为它会严重破坏页面。

为后代保留,请勿使用:

document.body.innerHTML = document.body.innerHTML.replaceAll(myVar, "<"+myTag+">"+myVar+</"+myTag+">");

有关 https://stackoverflow.com/a/17606289/6660122 和评论的更多信息。

 String.prototype.replaceAll = function(search, replacement) { var target = this; return target.split(search).join(replacement); }; document.body.innerHTML = document.body.innerHTML.replaceAll("Questions", "<b>Questions</b>");
 <p>Questions1</p> <p>Questions 2</p> <p>Questions 3</p> <p>Questions 4</p>

学习的好案例!

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • How to wrap part of all text_node nodeValue in an html element?
    I am iterating over all the text node in an html document in order to surround some words with a specific span. Changing the nodeValue doesn't allow me to insert html. The span is escaped to be shown in plain text and I do not want that. Here is what I have so far : var elements = document.getElementsByTagName('*'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; for (var j = 0; j < element.childNodes.length; j++) { var node = element.childNodes[j]; if (node.nodeType === Node.TEXT_NODE) { node.nodeValue = node.nodeValue.replace(/Questions/, "<span>Questions</span>"); } }
  • 如何使用来自 xml.dom 的 minidom 将内部内容作为字符串获取?(How to get inner content as string using minidom from xml.dom?)
    问题 我的 xml 文件中有一些文本标签(使用 popples-utils 中的 pdftohtml 将 pdf 转换为 xml),如下所示: <text top="525" left="170" width="603" height="16" font="1">..part of old large book</text> <text top="546" left="128" width="645" height="16" font="1">with many many pages and some <i>italics text among 'plain' text</i> and more and more text</text> <text top="566" left="128" width="642" height="16" font="1">etc...</text> 我可以使用此示例代码获取带有文本标签的文本: import string from xml.dom import minidom xmldoc = minidom.parse('../test/text.xml') itemlist = xmldoc.getElementsByTagName('text') some_tag = itemlist[node_index] output_text =
  • 如何将所有文本包装到唯一的跨度标签中?(How to wrap all text into unique span tag?)
    问题
  • 如何获取元素的文本节点?(How to get the text node of an element?)
    问题 <div class="title"> I am text node <a class="edit">Edit</a> </div> 我希望获得“我是文本节点”,不希望删除“ edit”标签,并且需要跨浏览器解决方案。 回答1 var text = $(".title").contents().filter(function() { return this.nodeType == Node.TEXT_NODE; }).text(); 这将获取所选元素的contents ,并对其应用过滤功能。 筛选器功能仅返回文本节点(即,那些节点类型为nodeType == Node.TEXT_NODE节点)。 回答2 您可以使用以下方法获取第一个childNode的nodeValue: $('.title')[0].childNodes[0].nodeValue http://jsfiddle.net/TU4FB/ 回答3 如果您要获取元素中第一个文本节点的值,则此代码将起作用: var oDiv = document.getElementById("MyDiv"); var firstText = ""; for (var i = 0; i < oDiv.childNodes.length; i++) { var curNode = oDiv.childNodes[i]; if
  • 如何获得元素后的文本节点?(How to get text node after element?)
    问题 使用jQuery。 我有以下html: <input type="checkbox" name='something' value='v1' /> All the world <br /> 我怎么会只得到文本。 我应该使用什么选择器? (我需要“全世界”) 我也无法触摸HTML ... 回答1 尝试使用DOM功能.nextSibling挑下一个节点(包括文本节点)和使用nodeValue来获取文本All the world $(':checkbox')[0].nextSibling.nodeValue 回答2 只需使用普通的JavaScript nextSibling ,尽管您必须“退出” jQuery才能使用该方法(因此[0] ): var text = $('input:checkbox[name="something"]')[0].nextSibling.nodeValue; JS Fiddle演示。 我终于意识到我的其他建议出了什么问题,该建议已得到解决: var text = $('input:checkbox[name="something"]').parent().contents().filter( function(){ return this.nodeType === 3 && this.nodeValue.trim() !== ''; }).first(
  • 使用Python最小化获取元素值(Get Element value with minidom with Python)
    问题 我正在使用Python创建Eve Online API的GUI前端。 我已经成功地从他们的服务器中提取了XML数据。 我正在尝试从名为“名称”的节点中获取值: from xml.dom.minidom import parse dom = parse("C:\\eve.xml") name = dom.getElementsByTagName('name') print name 这似乎找到了节点,但是输出如下: [<DOM Element: name at 0x11e6d28>] 我如何获取它以打印节点的值? 回答1 应该只是 name[0].firstChild.nodeValue 回答2 如果这是您想要的文字部分,可能是这样的事情... from xml.dom.minidom import parse dom = parse("C:\\eve.xml") name = dom.getElementsByTagName('name') print " ".join(t.nodeValue for t in name[0].childNodes if t.nodeType == t.TEXT_NODE) 节点的文本部分本身被认为是您所请求的节点的子节点。 因此,您将需要遍历其所有子节点,并找到所有作为文本节点的子节点。 一个节点可以有多个文本节点。 例如。 <name>
  • 使用JavaScript小书签,找到网页中所有“旧”实例,并将每个实例替换为“新”实例(Find all instances of 'old' in a webpage and replace each with 'new', using a javascript bookmarklet)
    问题 我想做的是用JS小书签或油脂猴子脚本中的“新”替换网页中“旧”的所有实例。 我怎样才能做到这一点? 我认为jQuery或其他框架还可以,因为有一些技巧可以将它们包含在小书签和油脂猴子脚本中。 回答1 防潮功能。 这意味着这将不会触摸任何标签或属性,而只会触摸文本。 function htmlreplace(a, b, element) { if (!element) element = document.body; var nodes = element.childNodes; for (var n=0; n<nodes.length; n++) { if (nodes[n].nodeType == Node.TEXT_NODE) { var r = new RegExp(a, 'gi'); nodes[n].textContent = nodes[n].textContent.replace(r, b); } else { htmlreplace(a, b, nodes[n]); } } } htmlreplace('a', 'r'); 书签版本: javascript:function htmlreplace(a,b,element){if(!element)element=document.body;var nodes=element.childNodes;for
  • 正则表达式仅搜索/替换文本,而不是 HTML 属性(Regexp to search/replace only text, not in HTML attribute)
    问题
  • 如何使用 JavaScript 将部分文本包裹在节点中(How to wrap part of a text in a node with JavaScript)
    问题 我有一个具有挑战性的问题要解决。 我正在编写一个将正则表达式作为输入的脚本。 然后,此脚本在文档中查找此正则表达式的所有匹配项,并将每个匹配项包装在其自己的 <span> 元素中。 困难的部分是文本是一个格式化的 html 文档,所以我的脚本需要在 DOM 中导航并一次在多个文本节点上应用正则表达式,同时找出如果需要它必须在何处拆分文本节点。 例如,使用捕获以大写字母开头并以句点结尾的完整句子的正则表达式,此文档: <p> <b>HTML</b> is a language used to make <b>websites.</b> It was developed by <i>CERN</i> employees in the early 90s. <p> 会变成这样: <p> <span><b>HTML</b> is a language used to make <b>websites.</b></span> <span>It was developed by <i>CERN</i> employees in the early 90s.</span> <p> 然后脚本返回所有创建的跨度列表。 我已经有一些代码可以找到所有的文本节点,并将它们连同它们在整个文档中的位置和深度一起存储在一个列表中。 你真的不需要理解那些代码来帮助我,它的递归结构可能有点令人困惑。
  • DOM TreeWalker 返回所有文本节点(DOM TreeWalker to return all text nodes)
    问题 我试图访问给定元素中的所有文本节点,以便我可以隔离单词并将它们包装在跨度中。 TreeWalker似乎是这项工作的 API,但我发现它非常不直观。 在我看来,规范和 MDN 参考(通常非常擅长解释神秘的 DOM API)都不是不言而喻的。 我的第一个假设是我需要传递的只是作为第二个参数的正确过滤器 - 类似于document.createTreeWalker( element, NodeFilter.TEXT_NODE ) 。 但这似乎在遇到非文本节点时立即停止: wordWrap( document.body ) function wordWrap( element ){ var nodes = document.createTreeWalker( element, NodeFilter.TEXT_NODE ) var node var text var word while( node = nodes.nextNode() ){ text = node.nodeValue.replace( /(^\s+|\s+$)/, '' ).split( /\s+/g ) while( text.length ){ word = document.createElement( 'span' ) word.className = 'word' word.innerText = text
  • 如何获取光标下的单词?(How to get word under cursor?)
    问题 假设有一个mousestop事件附加到整个文档,当鼠标停止移动时,找出光标下的确切单词(如果有任何文本)的最佳方法是什么? 我可以从事件处理程序中获取底层 (jQuery) 元素 - $(document.elementFromPoint(e.clientX, e.clientY)) - 但接下来是什么? 到目前为止,我的想法是用副本替换命中元素中的所有文本节点,其中每个单词都包含在 DOM 元素中(还不知道是哪个),然后调用$(document.elementFromPoint(e.clientX, e.clientY))再次获取仅包含鼠标下的单词的元素。 但这似乎是一个复杂的计划,我想知道我是否遗漏了一些更简单的东西。 回答1 好吧,到目前为止还没有魔术,所以这里是枯燥乏味(但有效)的解决方案: $(document.body).mousemove(function(e){ var onmousestop = function() { function getHitWord(hit_elem) { var hit_word = ''; hit_elem = $(hit_elem); //text contents of hit element var text_nodes = hit_elem.contents().filter(function(){ return
  • DOM TreeWalker to return all text nodes
    I'm trying to get access to all text nodes within a given element, so that I can isolate words and wrap them in spans. TreeWalker seems to be the API for the job, but I'm finding it to be extremely unintuitive. Neither the spec nor the MDN reference (usually so good at explaining arcane DOM APIs) are self-evident to my eyes. My first assumption was that all I needed to pass was the right filter as second argument - something like document.createTreeWalker( element, NodeFilter.TEXT_NODE ). But this seems to stop as soon as it encounters a non-text node: wordWrap( document.body ) function
  • How to wrap part of a text in a node with JavaScript
    I have a challenging problem to solve. I'm working on a script which takes a regex as an input. This script then finds all matches for this regex in a document and wraps each match in its own <span> element. The hard part is that the text is a formatted html document, so my script needs to navigate through the DOM and apply the regex across multiple text nodes at once, while figuring out where it has to split text nodes if needed. For example, with a regex that captures full sentences starting with a capital letter and ending with a period, this document: <p> <b>HTML</b> is a language used to
  • DOM 节点类型概述
    转载自:http://www.cnblogs.com/zhaowy/ 一般节点至少拥有 nodeType 、nodeName 和 nodeValue 这三个基本属性。节点类型不同,这三个属性的值也不相同。 NodeType nodeType属性返回节点类型的常数值。不同的类型对应不同的常数值,12种类型分别对应1到12的常数值。 元素节点   Node.ELEMENT_NODE(1) 属性节点   Node.ATTRIBUTE_NODE(2) 文本节点   Node.TEXT_NODE(3) CDATA节点 Node.CDATA_SECTION_NODE(4) 实体引用名称节点    Node.ENTRY_REFERENCE_NODE(5) 实体名称节点   Node.ENTITY_NODE(6) 处理指令节点   Node.PROCESSING_INSTRUCTION_NODE(7) 注释节点   Node.COMMENT_NODE(8) 文档节点   Node.DOCUMENT_NODE(9) 文档类型节点   Node.DOCUMENT_TYPE_NODE(10) 文档片段节点   Node.DOCUMENT_FRAGMENT_NODE(11) DTD声明节点 Node.NOTATION_NODE(12) NodeName 返回节点名称 NodeValue
  • 如何使用 Selenium 或 Protractor 获取 HTML 中嵌套元素的文本以进行自动化?(How do i get the text of a nested element in HTML for automation using Selenium or Protractor?)
    问题 我有以下 HTML 代码。 我需要控制台日志或仅打印desc类文本 - “打印此”而不是量角器或硒中的spell类文本。 <span class="desc"> Print this <a class="new-link" href="#"> <span class="spell">And not this</span> </a> </span> 我试图getText()但它用下面的代码打印完整的语句 - 打印这个 而不是这个 在使用 Javascript 的量角器中: element(by.css('.desc')).getText().then(function(text){ console.log(text); }); 在使用 Java 的 Selenium 中: System.out.println(driver.findElement(by.xpath('//*[@class=".desc"]')).getText()); 我如何只打印文本的第一部分(即“打印这个”)? 任何建议或帮助将不胜感激? 谢谢。 回答1 ElementFinder.getText()在元素上调用innerHTML并删除前导和尾随空格,但innerHTML还包括任何嵌套级别的所有子元素。 DOM 中没有特殊属性只能获取一级文本,但可以自己实现。 DOM 中的文本也是一个节点,存储在 DOM
  • 如何使用jquery获取父元素的文本?(How to get the text of parent element using jquery?)
    问题 我有一个包含删除超链接的 div,点击它,我想要 div 标签的文本。 在 jquery 中怎么可能?! <div>sometext<a href="#">delete</a></div> 我想获取 div 标签“sometext”的文本,如果可能的话,还有那个 div 的 id。 有任何想法吗?! 回答1 这样做的问题: $(this).parent().text(); 是它将获取 div 中的所有文本(sometext AND delete)。 我假设您只想要 div 中的文本而不是链接。 我在 jsFiddle 上举了一个例子: http://jsfiddle.net/HK794/ 理想情况下,您可能希望将文本包裹在一个跨度中,例如: <div id="div1"><span>sometext</span><a href="#">delete</a></div> 那么你的 JavaScript 将是: $("a").click(function(e){ $div = $(this).parent("div"); id = $div.attr("id"); text = $div.find("span").text(); alert( text ); e.preventDefault(); }); 编辑 正如@DarthJDG 所说,如果你不想改变你的标记
  • 如何使用jQuery选择文本节点?(How do I select text nodes with jQuery?)
    问题 我想获取一个元素的所有后代文本节点,作为jQuery集合。 最好的方法是什么? 回答1 jQuery对此没有方便的功能。 您需要将contents()仅提供子节点但包括文本节点)与find() ,后者将提供所有后代元素,但不提供文本节点。 这是我想出的: var getTextNodesIn = function(el) { return $(el).find(":not(iframe)").addBack().contents().filter(function() { return this.nodeType == 3; }); }; getTextNodesIn(el); 注意:如果您使用的是jQuery 1.7或更早版本,则上面的代码将不起作用。 要解决此问题,请用andSelf()替换addBack()。 andSelf()从1.8开始不推荐使用addBack() 。 与纯DOM方法相比,这种方法效率低下,并且必须为jQuery的content()函数的重载提供一个丑陋的解决方法(感谢注释中的@rabidsnail指出),因此这是使用简单递归的非jQuery解决方案功能。 includeWhitespaceNodes参数控制输出中是否包含空格文本节点(在jQuery中,它们会自动过滤掉)。 更新:修复了includeWhitespaceNodes虚假时的错误。
  • JQuery 更改所有元素文本(JQuery change all elements text)
    问题 我需要 jquery 来更改所有页面中的数字。 例如,我想将 1 更改为 ۱ 所以我尝试了这种方式: $("*").each(function(){ $(this).html( $(this).html().replace(1,"۱") ); }) 但这也会改变 css 规则和属性。 有什么技巧可以逃避css和属性吗? 回答1 这不是 jQuery 自然适合的工作。 不是让 jQuery 获取所有元素的平面列表,而是自己递归遍历 DOM 树,搜索文本节点以执行替换。 function recursiveReplace(node) { if (node.nodeType === Node.TEXT_NODE) { node.nodeValue = node.nodeValue.replace("1", "۱"); } else if (node.nodeType == Node.ELEMENT_NODE) { $(node).contents().each(function () { recursiveReplace(this); }); } } recursiveReplace(document.body); 在这里查看它的实际效果。 回答2 尝试这个: $("body *").each(function() { if ( this.childElementCount > 0
  • 制作/查找html5验证器书签(Making/finding html5 validator bookmarklet)
    问题 我想找到或制作一个书签,该书签将使用W3C HTML 5验证程序来验证当前查看页面的html内容。 我发现了两个小书签,并且试图使一个小书签的行为有点像另一个小书签的行为,但是我不确定如何做到这一点。 Chris Coyier拥有一个HTML5验证书签,除了使用页面URI之外,它都能很好地工作,因此不适用于本地测试的网站: javascript:(function(){%20function%20fixFileUrl(u)%20{%20var%20windows,u;%20windows%20=%20(navigator.platform.indexOf("Win")%20!=%20-1);%20%20/*%20chop%20off%20file:///,%20unescape%20each%20%hh,%20convert%20/%20to%20\%20and%20|%20to%20:%20*/%20%20u%20=%20u.substr(windows%20?%208%20:%207);%20u%20=%20unescape(u);%20if(windows)%20{%20u%20=%20u.replace(/\//g,"\");%20u%20=%20u.replace(/\|/g,":");%20}%20return%20u;%20}%20/*
  • 使用JS查找并替换文档中的特定文本字符(Find and replace specific text characters across a document with JS)
    问题 我想知道是否有一种轻量级的方法可以使用JavaScript或jQuery嗅探整个文档中的特定文本字符; 说出€并找到该字符的所有实例。 然后! 写一个能力,用$代替所有实例。 我找到了适合初学者的代码段: var str = 'test: ''; str = str.replace(/'/g, "'"); 本质上; 我想要一个一页文档的解决方案。 抓住X的所有实例,使其成为XY。 仅文字字符。 回答1 怎么样,用$代替@ : $("body").children().each(function () { $(this).html( $(this).html().replace(/@/g,"$") ); }); http://jsfiddle.net/maximua/jp96C/1/ 回答2 我自己的建议如下: function nativeSelector() { var elements = document.querySelectorAll("body, body *"); var results = []; var child; for(var i = 0; i < elements.length; i++) { child = elements[i].childNodes[0]; if(elements[i].hasChildNodes() && child