目前我在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
(使用“Contains”扩展jquery,如下所示)
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
另外,我使用jquery plugin突出显示结果,所以我认为这会使事情复杂化。如果需要,突出显示可能会对标点符号妨碍的地方失效。
当然,效率越高越好,因为这将成为移动应用程序的一部分......如果从搜索中删除info类需要花费大量时间,我将不得不将其从文件中删除,因为它不是绝对必要。
我发现here中的以下代码可能有所帮助,它应该删除无效字符,但不知道如何使用我有限的编码功能将其合并到自定义包含函数中。
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();
};
答案 0 :(得分:1)
为什么不直接使用Javascript来完成此操作?一个简单的正则表达式应该可以做到这一点:
str.replace(/[^a-z0-9\s]/gi, '')
这将采用字符串str
并删除任何不是数字或字母的字符(字母数字)。如果我是你,我不会覆盖原始的HTML(除非那是当然的重点),而是我将HTML的值存储在一个字符串str
中,然后做你讨厌的正则表达式在那里。这样原始HTML就会保持原状,如果你愿意,你仍然可以使用新的字符串并输出。真的不需要jQuery,:contains
只会slow you down。
答案 1 :(得分:1)
如果你通过id直接找到一个元素,然后从那里过滤,jQuery工作得最快。所以,我假设你的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()...
注意: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
}
}
});
这个版本应该比循环遍历每一行更快。另请注意,我已从index
调用中删除index2
和.each
个变量,因为您不使用它们。