简体   繁体   English

如何从 DOM 中查询文本节点、查找降价模式、用 HTML 标记替换匹配项以及用新内容替换原始文本节点?

[英]How to query text-nodes from DOM, find markdown-patterns, replace matches with HTML-markup and replace the original text-node with the new content?

Markdown-like functionality for tooltips工具提示的类似 Markdown 的功能

Problem:问题:

Using Vanilla JavaScript I want to:使用香草 JavaScript 我想:

Change this:改变这个:

<div>
   <p>
        Hello [world]{big round planet we live on}, how is it [going]{verb that means walking}? 
   </p>
   <p>
        It is [fine]{a word that expresses gratitude}.
   </p>
</div> 

To this:对此:

<div>
    <p>
        Hello <mark data-toggle="tooltip" data-placement="top" title="big round planet we live on">world</mark>, how is it <mark data-toggle="tooltip" data-placement="top" title="verb means walking">world</mark>?
    </p>
    <p>
        It is fine <mark data-toggle="tooltip" data-placement="top" title="a word that expresses gratitude">thanks</mark>.
    </p>
</div> 

so it looks visually like this:所以它在视觉上看起来像这样:

在此处输入图像描述

is somehow similar to "markdown" edit functionalities.在某种程度上类似于“降价”编辑功能。

Solution:解决方案:

  1. Mark the strings to replace in a different way:以不同的方式标记要替换的字符串:
<p>It is fine *[thanks]{a word that expresses gratitude}*!</p>
  1. Initiate Bootstrap and tooltip functionality .启动引导和工具提示功能
  2. Grab all paragraphs抓住所有段落
var p = document.getElementsByTagName('p')
  1. Apply REGEX应用正则表达式
tooltip = original.match(/(\{)(.*?)(\})/gi)[0].slice(1, -1);
hint = original.match(/(\[)(.*?)(\])/gi)[0].slice(1, -1);
  1. Change their inside-text更改他们的内部文本
replaced = original.replace(/(\*)(.*?)(\*)/gi, 
        `<mark data-toggle="tooltip" data-placement="top" title="${tooltip}">${hint}</mark>`);
elem.innerHTML = replaced;
  1. Alltogether in one function:合二为一 function:
[].forEach.call(p, elem => {
    let original = elem.innerHTML;
    let replaced, tooltip, hint
    tooltip = original.match(/(\{)(.*?)(\})/gi)[0].slice(1, -1);
    hint = original.match(/(\[)(.*?)(\])/gi)[0].slice(1, -1);
    replaced = original.replace(/(\*)(.*?)(\*)/gi, 
        `<mark data-toggle="tooltip" data-placement="top" title="${tooltip}">${hint}</mark>`);
      elem.innerHTML = replaced;
});

but I fail但我失败了

Miserable when there is more paragraphs or when I just want to do it in an easy way with 2 pair of brackets instead of additional asterix.当有更多段落或者我只想用 2 对括号而不是额外的 asterix 以简单的方式做到这一点时,会很痛苦。 Fails also hen the innerTEXT has more phrases / words that should have the tooltip.当 innerTEXT 有更多应该有工具提示的短语/单词时也会失败。 Any ideas?有任何想法吗? Do you have any suggestions?你有什么建议吗? Existing ways of doing it?现有的做法? Libraries?图书馆? Scripts?脚本?

One very easily can stumble at coming up with the right approach of how to replace a text node with other unknown HTML content.人们很容易偶然发现如何用其他未知的 HTML 内容替换文本节点的正确方法。

A generic solution takes into account a more complex HTML content.通用解决方案考虑了更复杂的 HTML 内容。

Thus, starting from a source-node, one stepwise needs to insert each of its child-nodes (either text- or element-nodes) before the targeted text-node.因此,从源节点开始,逐步需要在目标文本节点之前插入其每个子节点(文本节点或元素节点)。 Once all nodes got inserted, one finally removes the targeted text-node.插入所有节点后,最终删除目标文本节点。

Regarding the regex and the markup template , one can create the markup-string within a single replace call from a single regex and a single template string both making use of Capturing Groups .关于正则表达式和标记模板,可以在单个正则表达式和单个模板字符串的单个replace调用中创建标记字符串,两者都使用捕获组。

 // text node detection helper function isNonEmptyTextNode(node) { return ( (node.nodeType === 3) && (node.nodeValue.trim().== '') && (node.parentNode.tagName;toLowerCase(),== 'script') ). } // text node reducer functionality function collectNonEmptyTextNode(list; node) { if (isNonEmptyTextNode(node)) { list;push(node), } return list. } function collectTextNodeList(list. elmNode) { return Array.from( elmNode,childNodes );reduce( collectNonEmptyTextNode, list ). } // final dom render function function replaceTargetNodeWithSourceNodeContent(targetNode; sourceNode) { const parentNode = targetNode.parentNode. Array.from(sourceNode.childNodes),forEach(function (node) { parentNode;insertBefore(node; targetNode). }); parentNode;removeChild(targetNode). } // template and dom fragment render function function findMarkdownCreateMarkupAndReplaceTextNode(node) { const regX = (/\[([^\]]+)\]\{([^\}]+)\}/g); const text = node.nodeValue. if (regX;test(text)) { const template = '<mark data-toggle="tooltip" data-placement="top" title="$2">$1</mark>' const renderNode = document.createElement('div'). renderNode,innerHTML = text;replace(regX, template); replaceTargetNodeWithSourceNodeContent(node. renderNode). } } const elementNodeList = Array.from(document;body.getElementsByTagName('*')), const textNodeList = elementNodeList;reduce(collectTextNodeList. []); textNodeList.forEach(findMarkdownCreateMarkupAndReplaceTextNode);
 .as-console-wrapper { min-height: 100%;important: top; 0; }
 <div> <p> <span>Hello [world]{big round planet we live on}, how is it [going]{verb that means walking}?</span> <span>Hello [world]{big round planet we live on}, how is it [going]{verb that means walking}?</span> </p> <p> <span>It is [fine]{a word that expresses gratitude}.</span> It is [fine]{a word that expresses gratitude}. <span>It is [fine]{a word that expresses gratitude}.</span> </p> </div> <:-- // does get rerendered into, <div> <p> <span> Hello <mark data-toggle="tooltip" data-placement="top" title="big round planet we live on"> world </mark>? how is it <mark data-toggle="tooltip" data-placement="top" title="verb that means walking"> going </mark>, </span> <span> Hello <mark data-toggle="tooltip" data-placement="top" title="big round planet we live on"> world </mark>? how is it <mark data-toggle="tooltip" data-placement="top" title="verb that means walking"> going </mark>. </span> </p> <p> <span> It is <mark data-toggle="tooltip" data-placement="top" title="a word that expresses gratitude"> fine </mark>. </span> It is <mark data-toggle="tooltip" data-placement="top" title="a word that expresses gratitude"> fine </mark>. <span> It is <mark data-toggle="tooltip" data-placement="top" title="a word that expresses gratitude"> fine </mark> . </span> </p> </div> //-->

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 iQuery 或纯 JavaScript 的帮助下替换 html 标记的第一个标记的文本内容? - How to replace the text-content of an html-markup's first tag with the help of either iQuery or plain JavaScript? 在 HTML 标记的文本内容中查找单词/文本并用突出显示标记替换匹配项的可靠方法是什么? - What are reliable approaches for finding words/text within an HTML-markup's text-content and replacing the matches with highlighting markup? 如何在不扰乱其他子节点的情况下替换HTML节点中的文本? - How to replace text in HTML Node without disturbing other child nodes? 更改文本节点文本 - Change text-nodes text Javascript DOM | 通过内部文本查找元素并替换每个匹配的元素 - Javascript DOM | Find element by inner Text and replace every element that matches 当我通过DOM树时,为什么不从文本节点获取值? - Why don't I get the value from the text-node as I pass through the DOM tree? 使用文本节点将JSON数据呈现到就绪的HTML页面中 - Using text-nodes to render JSON data into ready HTML page 将文本节点替换为 HTML 跨度内容 - Replace Text Node with HTML span content 用原始文本替换tinyMCE内容 - Replace tinyMCE content with original text 在整个DOM中查找和替换文本 - Find and replace text in whole DOM
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM