将TextNode中的文本替换为基于正则表达式的新DOM节点
Replacing text in TextNode with new DOM node based on regular expression
我有一个函数可以预处理HTML DOM中的文本节点。
其目的本质上是执行一些插值或字符串模板。
该函数基本上检查与正则表达式/'${([^}]*)}/g
和/{{([^}]*)}/g
匹配的出现。
示例:${foo + 1}
和{{foo + 2}}
这一切都奏效了。
但我的目标是用新的节点(例如span
(替换这些出现,这些节点由Knockout绑定表达式组成,其中包含正则表达式中匹配项的内部值。位置正确。在出现空白的地方保留空白。
像这样:
<span ko-text="foo" />
用于${foo}
(注意:自定义绑定语法(
我就是无法用TextNode.splitText
来理解它。
我该如何做到这一点?
这是我目前掌握的代码:
preprocessNode(node: Element) {
if ("nodeValue" in node && node.nodeValue !== null) {
var value = node.nodeValue;
var match = value.matchAll(/'${([^}]*)}/g);
if (!match) {
match = value.matchAll(/{{([^}]*)}/g);
}
if (match !== null && match.length > 0) {
var parentNode = node.parentNode;
for (let entry of match) {
var offset = node.nodeValue.indexOf(entry[0]);
var oldNode = node;
node = node.splitText(offset);
var newNode = document.createElement("span");
newNode.setAttribute("ko-text", entry[1]);
node.parentNode.appendChild(newNode);
}
return [parentNode, parentNode];
}
}
return null;
}
函数matchAll
是一个自定义函数。
免责声明:我不懂JavaScript!这只是一个建议。
# /^'$'{([^{}]+)'}|'{'{([^{}]+)'}'}|((?:(?!^'$'{[^{}]+'}|'{'{[^{}]+'}'})['S's])+)/
^ '$'{
( [^{}]+ ) # (1)
'}
|
'{'{
( [^{}]+ ) # (2)
'}'}
|
( # (3 start)
(?:
(?!
^ '$'{ [^{}]+ '}
| '{'{ [^{}]+ '}'}
)
['S's]
)+
) # (3 end)
伪代码:
if ( regex_find ( /^'$'{[^{}]+'}|'{'{[^{}]+'}'}/, value ) )
{
var found = false;
while ( regex_search ( /^'$'{([^{}]+)'}|'{'{([^{}]+)'}'}|((?:(?!^'$'{[^{}]+'}|'{'{[^{}]+'}'})['S's])+)/g, match, value ) )
{
if ( match[1] != null )
{
// Found '${..}' form
found = true;
var newNode = document.createElement("span");
newNode.setAttribute("ko-text", match[1]);
// Append newNode
}
else
if ( match[2] != null )
{
// Found '{{..}}' form
found = true;
var newNode = document.createElement("span");
newNode.setAttribute("ko-text", match[2]);
// Append newNode
}
else
if ( match[3] != null )
{
// Found '...' normal text
found = true;
var newNode = document.createTextNode( match[3] );
// Append newNode
}
}
if ( found )
{
// Clear or delete the original text node
// ...
}
}
经过多次考虑,我就是这样解决的:
if (match !== null && match.length > 0) {
var parentNode = node.parentNode;
var nodes = [];
var textString = value;
var i = 0;
for (let entry of match) {
var startOffset = node.nodeValue.indexOf(entry[0]);
var endOffset = startOffset + entry[0].length;
var length = startOffset - i;
if (length > 0) {
var str = textString.substr(i, length);
var textNode = document.createTextNode(str);
parentNode.insertBefore(textNode, node);
}
var newNode2 = document.createElement("span");
newNode2.setAttribute("ko-text", entry[1]);
parentNode.insertBefore(newNode2, node);
nodes.push(newNode2);
i = endOffset;
}
var length = textString.length - i;
if (length > 0) {
var str = textString.substr(i, length);
var textNode = document.createTextNode(str);
parentNode.insertBefore(textNode, node);
}
parentNode.removeChild(node);
return nodes;
}
它肯定可以改进。
var textNodesWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
var node;
while (node = textNodesWalker.nextNode()) {
var newNodes = [];
var execResult = MY_REG_EXP.exec(node.nodeValue);
var start = 0;
while (execResult) {
newNodes.push(document.createTextNode(node.nodeValue.substring(start, execResult.index)));
var generatedElement = ...; // create element (document.createElement) based on execResult
newNodes.push(generatedElement);
start = execResult.index + execResult[0].length;
execResult = MY_REG_EXP.exec(node.nodeValue);
}
if (newNodes.length == 0) {
continue;
}
newNodes.push(document.createTextNode(node.nodeValue.substring(start, node.nodeValue.length)));
for (var i=0; i<newNodes.length; i++) {
node.parentNode.insertBefore(newNodes[i], node)
}
node.parentNode.removeChild(node);
}
让我们假设我们有模式/asdf/g
,而不需要加粗。我的代码将转换以下html:
<p>Begin asdf End</p>
至
<p>Begin <b>asdf</b> End</p>
相关文章:
- java.net和javascript之间正则表达式的差异
- Grunt匹配正则表达式
- 不同浏览器中的空白字符正则表达式行为
- 正则表达式在字符串中找到base64
- 子字符串/正则表达式以获取字符串中保存的 SRC 值
- 调用正则表达式匹配的函数
- 使用正则表达式评估电子邮件地址时出现性能问题
- Javascript 正则表达式 : ^[^/s/]+[a-z]{1,}[0-9]*[-_]*[^/][
- JavaScript正则表达式文本与RegExp对象
- 正则表达式只允许 x 个整数
- 使用正则表达式将输入格式设置为单字符逗号、单字符逗号等
- 改进用于验证付款金额的正则表达式
- 正则表达式与数字中的第二个点匹配
- 键按正则表达式以查找具有负值的小数
- 一个正则表达式,用于从JS中的HTML标记中删除id、样式和类属性
- 将po-box javascript正则表达式转换为c#regex
- 在 Javascript 中使用正则表达式解析 XHTML 字符串并将其转换为 DOM
- 从DOM ID中删除非法字符的Javascript正则表达式
- 查找包含字符串匹配正则表达式的DOM元素
- 将TextNode中的文本替换为基于正则表达式的新DOM节点