通常 jQuery を使用するレベルより下のレベルでこれを行う必要があります: テキスト ノード。
この HTML:
<p>Hi there</p>
p
単一のテキスト ノードを含む要素を生成します。通常、jQuery では要素のみを操作しますが、非破壊的に (すべての要素を削除して再作成することなく、すべてのイベント ハンドラーをアンフックすることなく) 行うには、次を使用してノード レベルで作業する必要があります。 DOMsplitText
やinsertBefore
メソッドなどのツール。
複雑ではありませんが、異なるレベルで作業することを意味します。
スタック オーバーフローに関する私の他の回答では、ドキュメントのテキスト ノードをたどり、その中のテキストを検索し、分割してラッパー要素 (この場合は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;
}
}
3行くらい変えただけ。