我想知道是否有一种轻量级方式我可以使用JavaScript或jQuery来嗅出文档中的特定文本字符; 说€并找到这个角色的所有实例.然后!写一个用$替换所有实例的能力.
我找到了这个首发代码片段:
var str = 'test: ''; str = str.replace(/'/g, "'");
实质上; 我想要一个单页文档的解决方案.抓住X的所有实例并使其成为XY.只有文字字符.
怎么样,替换@
为$
:
$("body").children().each(function () { $(this).html( $(this).html().replace(/@/g,"$") ); });
http://jsfiddle.net/maximua/jp96C/1/
我个人的建议如下:
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.nodeType == 3) { results.push(child); } } return results; } var textnodes = nativeSelector(), _nv; for (var i = 0, len = textnodes.length; iJS小提琴演示.
该
nativeSelector()
函数来自一个答案(由Anurag发布)到这个问题:getElementsByTagName()等效于textNodes.
3> Sebastian Si..:ECMAScript 2015+方法
解决此任务时的陷阱
这似乎是一件容易的事,但你必须要处理好几件事:
简单地替换整个HTML会杀死所有DOM功能,例如事件侦听器
替换HTML也可能替换
或
内容,或HTML标签或属性,这并不总是需要
更改HTML可能会导致xss攻击
您可能还想替换类似
title
和alt
(以受控方式)的属性
通常使用以下方法无法解决防御xss攻击的问题.例如,如果
fetch
呼叫从页面上的某个位置读取URL,然后向该URL发送请求,则下面的功能将不会停止,因为这种情况本质上是不安全的.替换所有元素的文本内容
这基本上选择包含普通文本的所有元素,遍历其子节点 - 其中也包括文本节点 - ,寻找那些文本节点并替换它们的内容.
您可以选择指定不同的根
target
,例如replaceOnDocument(/€/g, "$", { target: someElement });
; 默认情况下,选择.
const replaceOnDocument = (pattern, string, {target = document.body} = {}) => { // Handle `string`?—?see the last section [ target, ...target.querySelectorAll("*:not(script):not(noscript):not(style)") ].forEach(({childNodes: [...nodes]}) => nodes .filter(({nodeType}) => nodeType === document.TEXT_NODE) .forEach((textNode) => textNode.textContent = textNode.textContent.replace(pattern, string))); }; replaceOnDocument(/€/g, "$");替换文本节点,元素属性和属性
现在,这有点复杂:你需要检查三种情况:一个节点是一个文本节点,它是一个元素还是它的属性应该被替换,或者它是否是一个元素,它的属性应该被替换.甲
replacer
对象提供用于文本节点和元件的方法.在替换属性和属性之前,替换者需要检查元素是否具有匹配的属性; 否则会产生新的属性.它还需要检查目标属性是否是字符串,因为只能替换字符串,或者目标属性的匹配属性是否不是函数,因为这可能导致xss攻击.
在下面的示例中,您可以看到如何使用扩展功能:在可选的第三个参数中,您可以添加
attrs
属性和props
属性,每个属性都是可迭代的(例如数组),用于要替换的属性和属性分别被替换.您还会注意到此代码段使用了
flatMap
.如果不支持,请使用polyfill或用reduce
-concat
或map
-reduce
-concat
构造替换它,如链接文档中所示.const replaceOnDocument = (() => { const replacer = { [document.TEXT_NODE](node, pattern, string){ node.textContent = node.textContent.replace(pattern, string); }, [document.ELEMENT_NODE](node, pattern, string, {attrs, props} = {}){ attrs.forEach((attr) => { if(typeof node[attr] !== "function" && node.hasAttribute(attr)){ node.setAttribute(attr, node.getAttribute(attr).replace(pattern, string)); } }); props.forEach((prop) => { if(typeof node[prop] === "string" && node.hasAttribute(prop)){ node[prop] = node[prop].replace(pattern, string); } }); } }; return (pattern, string, {target = document.body, attrs: [...attrs] = [], props: [...props] = []} = {}) => { // Handle `string`?—?see the last section [ target, ...[ target, ...target.querySelectorAll("*:not(script):not(noscript):not(style)") ].flatMap(({childNodes: [...nodes]}) => nodes) ].filter(({nodeType}) => replacer.hasOwnProperty(nodeType)) .forEach((node) => replacer[node.nodeType](node, pattern, string, { attrs, props })); }; })(); replaceOnDocument(/€/g, "$", { attrs: [ "title", "alt", "onerror" // This will be ignored ], props: [ "value" // Changing an ``’s `value` attribute won’t change its current value, so the property needs to be accessed here ] });替换为HTML实体
如果你需要让它与HTML实体一起使用
,上面的方法只会字面上产生字符串
,因为它是一个HTML实体,只有在分配.innerHTML
或使用相关方法时才有效.所以让我们通过将输入字符串传递给接受HTML字符串的东西来解决它:一个新的,临时的
HTMLDocument
.这由创建DOMParser
的parseFromString
方法; 最后我们读了它documentElement
的textContent
:string = new DOMParser().parseFromString(string, "text/html").documentElement.textContent;如果要使用此方法,请选择上述方法之一,具体取决于您是否要替换除文本之外的HTML属性和DOM属性; 然后简单地用
// Handle `string`?—?see the last section
上面的行替换注释.现在你可以使用了
replaceOnDocument(/Güterzug/g, "Güterzug");
.注意:如果您不使用字符串处理代码,您也可以删除
{
}
箭头函数体周围.请注意,这解析HTML实体但仍然不允许插入实际的HTML标记,因为我们只读取
textContent
.对于xss的大多数情况,这也是安全的:因为我们正在使用parseFromString
并且页面document
不受影响,所以不会下载并且不会
onerror
执行处理程序.如果结果更简单,您还应该考虑使用
\xAD
而不是
直接在JavaScript字符串中使用.