5

次のような 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を使用して、この方法でドキュメント内のプレーンテキストのみを一致させて置き換える方法を知っている人はいますか?

4

4 に答える 4

8

nodeTypeでをフィルタリングしてテキスト ノードのみを取得し、jQuery で生成されたアンカー要素に置き換えてみてください (これらのノードの余分なテキストはテキスト ノードとして保持されます)。bodycontents()

$('body').contents().filter(function() {
    return this.nodeType === 3;
}).each(function() {
    $(this).replaceWith($(this).text().replace(/(00\d+)/g, '<a href="#$1">$1</a>'));
});

フィドル

ご存知のように、ほとんどの場合、HTML を Regex で解析するのは良い考えではありません (ポニーに気をつけてください。彼らは邪悪です)。しかし、解析したい HTML の一部を分離し、それが比較的単純なパターンに従う場合実行可能なオプションです。

編集:正規表現にgフラグ (グローバル修飾子) を含めて、単一のテキスト ノード内で複数のアンカーを照合できるようにしました。

于 2012-07-26T02:35:47.637 に答える
6

最終的な解決策は次のようになりました。

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/

おかげで:

于 2012-07-26T03:54:42.877 に答える
0

これは、ボビンスによる質問への関連する回答から:

正規表現で HTML を処理したくないのは当然です。.html(); の巨大なチャンクを割り当てることも悪いニュースです。大量の HTML をシリアル化および再解析することによるパフォーマンス上の欠点とは別に、イベント リスナー、フォーム データ、JS プロパティ/参照などのシリアル化できないデータも失われます。

これは、正規表現パターンの一致を許可する単純な JavaScript/DOM です。セレクターは要素しか選択できず、':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);
});
于 2012-07-26T02:31:19.457 に答える
0

これをぐるぐる回してみてください....もっときれいになりました!! ;)

$('input').each(function() {
    var temp;
       temp = $(this).val();
       $(this).before('<a href="#' + temp +'">' +temp+ '</a>');
});
$('body').contents().filter(function() {return this.nodeType == 3;}).remove();
于 2012-07-26T02:41:30.237 に答える