jQuery:如何将RegEx匹配的纯文本包装在锚标记中
jQuery: How to wrap RegEx matched plain text in an anchor tag?
假设我有一个HTML页面,看起来像这样:
<html><body>
00123
<input value="00123">
00456
</body></html>
我想使用javascript/jQuery让它看起来像这样:
<html><body>
<a href="#00123">00123</a>
<input value="00123">
<a href="#00456">00456</a>
</body></html>
从本质上讲,我想用HTML锚标记包装文档中与正则表达式匹配的纯字符串。在这个例子中,我想做一些类似的事情:
$('body').html($('body').html().replace(/(00'd+)/, '<a href="#$1">$1</a>'));
请参阅以下示例的jsFiddle:http://jsfiddle.net/NATnr/2/
此解决方案的问题是input
元素内的文本被匹配和替换。
有人知道如何使用javascript/jQuery以这种方式只匹配和替换文档中的纯文本吗?
尝试按nodeType过滤body
的contents()
以仅获得文本节点,然后用jQuery生成的锚元素替换它们(这些节点中的任何额外文本都将保留为文本节点):
$('body').contents().filter(function() {
return this.nodeType === 3;
}).each(function() {
$(this).replaceWith($(this).text().replace(/(00'd+)/g, '<a href="#$1">$1</a>'));
});
小提琴
正如你所知,用Regex解析HTML通常不是一个好主意(注意小马,它们是邪恶的),但如果你隔离了你想要解析的HTML的一部分,并且它遵循一个相对简单的模式,这是一个可行的选择。
编辑:在Regex中包含g
标志(全局修饰符),以允许在单个文本节点内匹配多个锚点。
最终的解决方案是这样的:
jQuery.fn.linker = function () {
$(this).contents()
.filter(function() { return this.nodeType != Node.TEXT_NODE; })
.each(function () { $(this).linker(); });
$(this).contents()
.filter(function() { return this.nodeType == Node.TEXT_NODE; })
.each(function () {
$(this).replaceWith(
$(this).text().replace(/(00'd+)/g, '<a href="#$1">$1</a>')
);
});
}
$(document).ready(function () {
$('body').linker();
});
在这里查看jsFiddle的工作:http://jsfiddle.net/fr4AL/4/
感谢:
- 法布里西奥的回答
- 如何使用jQuery选择文本节点
- http://api.jquery.com/wrap/
- http://api.jquery.com/contents/
- 将HTML字符串转换为DOM元素
这是bobince对一个问题的相关回答:
您不希望使用regex处理HTML是正确的。分配大量的.html()也是个坏消息;除了串行化和重新分析大量HTML的性能缺陷外,您还将丢失不可串行化的数据,如事件侦听器、表单数据和JS属性/引用。
这里有一个简单的JavaScript/DOM,它允许RegExp模式匹配。jQuery在这里并没有给你太多帮助,因为选择器只能选择元素,而":contains"选择器是递归的,所以对我们来说用处不大。
// Find text in descendents of an element, in reverse document order
// pattern must be a regexp with global flag
//
function findText(element, pattern, callback) {
for (var childi= element.childNodes.length; childi-->0;) {
var child= element.childNodes[childi];
if (child.nodeType==1) {
findText(child, pattern, callback);
} else if (child.nodeType==3) {
var matches= [];
var match;
while (match= pattern.exec(child.data))
matches.push(match);
for (var i= matches.length; i-->0;)
callback.call(window, child, matches[i]);
}
}
}
findText(document.body, /'bBuyNow'b/g, function(node, match) {
var span= document.createElement('span');
span.className= 'highlight';
node.splitText(match.index+6);
span.appendChild(node.splitText(match.index+3));
node.parentNode.insertBefore(span, node.nextSibling);
});
试试。。。。干净多了!!)
$('input').each(function() {
var temp;
temp = $(this).val();
$(this).before('<a href="#' + temp +'">' +temp+ '</a>');
});
$('body').contents().filter(function() {return this.nodeType == 3;}).remove();
- jquery在元素中查找文本节点,并使用标记进行连接和包装
- 如何在输入中选择的文本周围包装html标记
- 如何将所有文本包装成唯一的span标记
- 通过 jQuery Find and Replace 将文本 URL 与 标记包装在一起
- 如何将由
分隔的文本节点与它们自己的标记包装起来
- 如何使用jquery检测包装的纯文本并应用html标记
- 如何将新输入的文本包装到下面已经存在的span标记中
- 包装和打开jquery后合并文本节点
- 如何在启用designMode的iframe中包装文本,必要时使用css和javascript
- Javascript用标签bbcode包装文本
- 如何在myeclipse中包装文本
- 如何在两行上包装文本,每行上的数量相等
- 如何包装文本内的特定宽度和高度使用javascript向上滚动和向下滚动
- 如何在滑动导航面板中包装文本?
- <a>标记在由jQuery生成时未完全包装文本
- 如何在SVG中包装文本
- D3加上用圆圈包装文本
- 包装文本,使用调用函数传递数据
- javascript用标记包装文本
- 如何用HTML标签包装文本,但排除某些HTML标签内的文本