1

現在、html ファイル内の div 内を検索し、その中に結果が見つかった場合は hideMe クラスを削除して、見つかった賛美歌を明らかにします。検索から情報クラスを除外しながら、句読点なしで (入力と出力の両方から句読点を削除して) 賛美歌を検索できるかどうか疑問に思っています。

<div id="himnario">
   <div id="1" class="song hideMe">
      <div class="info">I don't want this info to be searched</div>
      <div class="tuneName">This tune should be searched</div>
      <ol>
         <li>Verse 1</li>
         <li>Verse 2</li>
      </ol>
   </div>
   <div id="2" class="song hideMe">...</div>
</div>

現在、私の検索コードは次のとおりです。

$("#himnario div.song:Contains("+item+")").removeClass('hideMe').highlight(item);
isHighlighted = true; //check if highlighted later and unhighlight, for better performance

(次のように「含む」でjqueryを拡張します)

return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; 

また、結果を強調表示するためにjqueryプラグインを使用しているため、これは複雑になると思います。必要に応じて、句読点が邪魔になる場所でハイライトが機能しなくなる可能性があります。

もちろん、これはモバイルアプリの一部になるため、より効率的であるほど良いです...検索から情報クラスを削除するのに時間がかかる場合は、絶対にそうではないため、ファイルから削除する必要があります必要不可欠。

ここから、無効な文字を削除するはずの次のコードを見つけましたが、コーディング能力が限られているため、それをカスタムの Contains 関数に適切に組み込む方法がわかりません。

Return Regex.Replace(strIn, "[^\w\.@-]", "")

ご協力いただきありがとうございます。

編集: @Nick のおかげで、推奨される解決策は次のとおりです。

$('#himnario').children().addClass('hideMe'); // hide all hymns
//http://stackoverflow.com/questions/12152098/jquery-search-contains-without-punctuation-excluding-specific-class
// Get rid of punctuation in your search item - this only allows alphanumeric
item2 = item.toUpperCase().replace(/<(.|\n)*?>|[^a-z0-9\s]/gi, ''); 
// Loop though each song
$('#himnario').children().each(function() {
    var $this_song = $(this);
    // Examine the song title & the ordered list, but not the hidden info (first child)
    $this_song.children('.tuneName, ol').each(function() {
        // Get the html, strip the punctuation and check if it contains the item
        if ($(this).html().toUpperCase().replace(/<(.|\n)*?>|[^a-z0-9\s]/gi, '').indexOf(item2) !== -1) {
            // If item is contained, change song class
            $this_song.removeClass('hideMe').highlight(item); //original search phrase
            isHighlighted = true; //check later, for better performance
            return false;   // Prevents examination of song lines if the title contains the item
        } 
    });            
});

ハイライト機能:

/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery.fn.highlight = function(pat) {
 function innerHighlight(node, pat) {
  var skip = 0;
  if (node.nodeType == 3) {
   var pos = node.data.toUpperCase().indexOf(pat);
   if (pos >= 0) {
    var spannode = document.createElement('span');
    spannode.className = 'highlight';
    var middlebit = node.splitText(pos);
    var endbit = middlebit.splitText(pat.length);
    var middleclone = middlebit.cloneNode(true);
    spannode.appendChild(middleclone);
    middlebit.parentNode.replaceChild(spannode, middlebit);
    skip = 1;
   }
  }
  else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
   for (var i = 0; i < node.childNodes.length; ++i) {
    i += innerHighlight(node.childNodes[i], pat);
   }
  }
  return skip;
 }
 return this.each(function() {
  innerHighlight(this, pat.toUpperCase());
 });
};

jQuery.fn.removeHighlight = function() {
 return this.find("span.highlight").each(function() {
  this.parentNode.firstChild.nodeName;
  with (this.parentNode) {
   replaceChild(this.firstChild, this);
   normalize();
  }
 }).end();
};
4

2 に答える 2

1

jQuery は、id で直接要素に移動し、そこからフィルター処理する場合に最も速く動作します。したがって、HTML は次のようになっていると仮定します。

<div id="himnario">
    <div id="1" class="song hideMe">
        <div class="info">Hidden text</div>
        <div class="tuneName">Search me!</div>
        <ol>
            <li>Verse 1</li> 
            <li>Verse 2</li>
        </ol>
    </div>
    <div id="2" class="song hideMe">
        ...
    </div>
</div>

最も効率的に曲を見つけるには、次のようにします。

$('#himnario').children()...

注:は、1 レベルの深さまでしか検索しないため、children()はるかに優れています。子として曲しかない場合は、find()指定しないと速度が上がります。.songもしそうなら、あなたはすでにはるかに速く進んでいます。

子を取得したらeach()、絶対に最速の方法ではない方法を使用できますが、問題ありません。したがって、これは各曲/子を調べます:

$('#himnario').children().each(function(index) {...});

あなたの場合:

// Get rid of punctuation in you search item - this only allows alphanumeric
item = item.replace(/[\W]/gi, '');

// Loop though each song
$('#himnario').children().each(function() {
    var $this_song = $(this);

    // Loop through each line in this song [EDIT: this doesn't account for the title]
    $this_song.find('li').each(function() {

        // Get the html from the line, strip the punctuation and check if it contains the item
        if $(this).html().replace(/[\W]/gi, '').indexOf(item) !== -1 {
            // If item is contained, change song class
            $this_song.removeClass('hideMe');
            return false;   // Stops each_line loop once found one instance of item
        } 
    }            
});

ハイライトは何もしていません。私もこれをテストしていませんが、小さなバグがあれば問題なく動作するはずです:)

編集:「曲のタイトル」フィールドに照らして、次のことができます:

// Get rid of punctuation in you search item - this only allows alphanumeric
item = item.replace(/[\W]/gi, '');

// Loop though each song
$('#himnario').children().each(function() {
    var $this_song = $(this);

    // Examine the song title & the ordered list, but not the hidden info (first child)
    $this_song.children().not(':first').each(function() {

        // Get the html, strip the punctuation and check if it contains the item
        if $(this).html().replace(/[\W]/gi, '').indexOf(item) !== -1 {
            // If item is contained, change song class
            $this_song.removeClass('hideMe');
            return false;   // Prevents examination of song lines if the title contains the item
        } 
    }            
});

このバージョンは、個々の行をループするよりも高速です。また、使用しないため、呼び出しから変数indexindex2変数を削除したことにも注意してください。.each

于 2012-08-28T04:10:51.657 に答える
1

これを実現するために、ストレートな Javascript を使用しないのはなぜですか? 単純な正規表現でうまくいくはずです:

str.replace(/[^a-z0-9\s]/gi, '')

これは文字列を取り、str数字または文字 (英数字) 以外の文字をすべて削除します。私があなただったら、元の HTML を上書きしません (もちろん、それが重要な場合を除きます)。代わりに、HTML の値を文字列 に保存し、strそこで厄介な正規表現を実行します。そうすれば、元の HTML はそのまま残り、必要に応じて新しい文字列を操作して出力することができます。jQuery は実際には必要ありません。速度が低下:containsするだけです。

于 2012-08-28T02:56:32.357 に答える