您需要在低于通常使用 jQuery 的级别执行此操作: 文本节点。
这个 HTML:
<p>Hi there</p>
生成一个p
包含单个文本节点的元素。通常使用 jQuery,您只使用元素,但要以非破坏性方式执行您正在执行的操作(不删除和重新创建所有元素,这将取消所有事件处理程序的挂钩),您需要在节点级别工作,使用DOMsplitText
和insertBefore
方法等工具。
这并不复杂,但它只是意味着在不同的层面上工作。
我在 Stack Overflow 上的另一个答案向您展示了如何遍历文档的文本节点,在其中定位文本,将其拆分并放入包装元素(在您的情况下为span
)。在这种情况下,代码使用简单的正则表达式来查找看起来像链接的文本并将其变成实际链接,例如更改:
<p>I found this information at http://stackoverflow.com.</p>
至
<p>I found this information at <a href="http://stackoverflow.com">http://stackoverflow.com</a>.</p>
您可以看到这与您想要做的非常非常相似。您基本上只需更改查找文本的方式,其余代码已经完成了这项工作。
这是该答案中的代码已更新为使用正则表达式来查找单词中的任何字符,这些字符在您为阿拉伯字符引用的范围内:
// The regex matches a series of characters in the given range.
// (Double-check this, I believe there's a second Arabic range in
// the Unicode standard, but I know next to nothing about Arabic.)
walk(document.body, /[\u0600-\u06FF]+/);
function walk(node, targetRe) {
var child;
switch (node.nodeType) {
case 1: // Element
for (child = node.firstChild;
child;
child = child.nextSibling) {
walk(child, targetRe);
}
break;
case 3: // Text node
handleText(node, targetRe);
break;
}
}
function handleText(node, targetRe) {
var match, targetNode, followingNode, wrapper;
// Does the text contain our target string?
match = targetRe.exec(node.nodeValue);
if (match) {
// Split at the beginning of the match
targetNode = node.splitText(match.index);
// Split at the end of the match.
// match[0] is the full text that was matched.
followingNode = targetNode.splitText(match[0].length);
// Wrap the target in an `span` element with an `arabic` class.
// First we create the wrapper and insert it in front
// of the target text. We use the first capture group
// as the `href`.
wrapper = document.createElement('span');
wrapper.className = "arabic";
targetNode.parentNode.insertBefore(wrapper, targetNode);
// Now we move the target text inside it
wrapper.appendChild(targetNode);
// Clean up any empty nodes (in case the target text
// was at the beginning or end of a text node)
if (node.nodeValue.length == 0) {
node.parentNode.removeChild(node);
}
if (followingNode.nodeValue.length == 0) {
followingNode.parentNode.removeChild(followingNode);
}
// Continue with the next match in the node, if any
match = followingNode
? targetRe.exec(followingNode.nodeValue)
: null;
}
}
只改变了大约三行。