jquery过滤器脚本不会忽略变音符号,并且不会突出显示字符串匹配,因为用户在文本输入字段中输入过滤器文本 [英] jquery filter script not ignoring diacritics and not highlighting string matches as user enters filter text into text input field

查看:127
本文介绍了jquery过滤器脚本不会忽略变音符号,并且不会突出显示字符串匹配,因为用户在文本输入字段中输入过滤器文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



在每个词汇表上方,我想让用户在文本输入中键入一个单词或短语字段仅查看包含键入的字符串(单词或短语)的表行。例如,如果在文本输入字段中输入good,则不包含字符串good的表格行将消失。如果您访问 http://www.amanado.com/idioma-colombiano/,点击Vocabulario(官方和德尔杰尔加) - palabras y frases comunes展开手风琴部分,然后在文字输入栏中输入good,在Ingresa palabra o frase en el siguiente campo para filtrar lainformaciónde la tabla。在文本输入框中输入good后,词表中的所有7行应该消失(剩余7行)。



我有以下3个问题:



1)我无法以同样的方式忽略重音符号(例如é,ñ,ü)该案件已被成功忽略。例如,如果用户在输入字段中输入que,则包含que和qué的行不应消失。但是,当您键入que时,包含qué的行会错误地消失。如您所见,如果您在输入字段中输入que(不包括引号),则包含que的2条记录将保留。而且,如果您在输入字段中键入或粘贴qué(不包括引号),则包含qué的6条记录将保留。

2) 我试图使用jquery.highlight.js版本来突出显示保持/不消失的行中的字符串匹配。有关如何以可视方式显示的示例,请在此问题摘要的第二段中指示的输入字段中键入que,您将看到字符串que在2行中突出显示,并保持/不消失。请注意,这不能正常工作,因为我通过插入脚本$(table td)。highlight(que);插入到html页面的head部分,目的是为了说明(a)jquery.highlight.js是主动/正在运行的,并且(b)提供突出显示的文本将如何显示的视觉示例。

3)除了使用户能够在字段中输入单词或短语以仅查看包含输入的单词或短语不能成功忽略重音符号(例如,é,ñ,ü),这是所需的行为,jquery.highlight.js脚本也未成功忽略重音符号(例如,é,ñ,ü)。例如,在本问题摘要的第二段中指示的输入字段中键入pues,您将在保留/不消失的行中未成功突出显示字符串Qué和qué的多个案例。请记住,我通过插入脚本$(table td)。highlight(que);到html页面的一部分,所以如果任何字符串que,,,所有字符串que,qué,Que和Qué (a)情况和(b)口音(例如,é,ñ,ü)被忽略的情况下,将qué,Que或Qué输入到输入字段。有趣的是,注意到ignoreAccents的功能性包含在我正在使用的jquery.highlight.js中。



下面是:输入字段,因为它出现在我的html中;

(b)我使用JavaScript来使用户能够在字段中输入单词或短语来仅查看包含输入的词或短语(为简洁起见,以下称为filter javascript);和



(c)我使用jquery.highlight.js javascript来突出显示文本。



请注意:我不是一名软件工程师,但是我知道如果有人告诉我要做什么具体操作(例如,进行确切的更改,做出这个确切的改变,然后做出这个确切的改变)。我很感谢任何人可以提供的帮助,并且文字说明会特别感谢。而且,我总是希望使用最少的代码(例如,javascript,css,html)来实现最大的目标。



其他笔记/注意事项包含在此问题摘要的底部。

(a)input field starts here

 < form class =live-searchaction =method =post> 
< p> Ingresa palabra o frase en el siguiente campo para filtrar lainformaciónde la tabla< / p>
< input class =input-text-trtype =textvalue =Mostrarsólofilas que contengan .../>
< span class =filter-count-tr>< / span>
< / form>

(a)输入字段在此处结束

$(b)过滤器javascript从这里开始

  $(function ){
$(。input-text-tr)。on('keyup',function(e){
var disallow = [37,38,39,40]; //忽略箭头($。inArray(e.which,disallow)> -1){
return true;
}
var inputField = this,
val = this.value,
pattern = new RegExp(val,i),
$ group = $(this).closest(。group),
$ trs = $ group。 find(。myTable tbody tr),
$ s;
if(val ===''){
$ s = $ trs;
}
其他{
$ s = $();
$ trs.stop(true,true).each(function(i,tr){
if(val!== inputField.value) {//如果用户已经做了另一次击键
返回false; //跳出.each()并因此退出事件处理程序
}
$ tr = $(tr);
if($ tr.text()。match(pattern)){
$ s = $ s.add(tr);
}
});
/ / $ trs.not($ s).fadeOut();
$ trs.not($ s).hide ();
}
$ group.find(。filter-count-tr)。text((+ $ s.show().length +)); (this.defaultValue == this.value)this.value ='';
else if(this.value
})。on('focus blur',function(){
if =='')this.value = this.defaultValue;
});

$(。group)。each(function(){
$ this = $(this);
$ this.find(。filter-count-tr ).text((+ $ this.find(tbody tr)。length +));
});
});

(b)过滤器javascript结束于此



(c)jquery.highlight.js javascript start here $ b

  jQuery.extend({
highlight:function(node,re,nodeName,className,ignoreAccents){$ b $ if(node.nodeType === 3){

var nodeData = node.data;
if(ignoreAccents){
nodeData = jQuery.removeDiacratics(nodeData);
}
var match = nodeData.match(re);
if (match){
var highlight = document.createElement(nodeName ||'span');
highlight.className = className ||'highlight'; var wordNode = node.splitText(match.index);
wordNode.splitText(match [0] .length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild (highlight,wordNode);
return 1; //跳过父节点中的添加节点
}
} else if((node.nodeType === 1&& node.childNodes)& amp ;& // only ele包含子
!/(script | style)/i.test(node.tagName)&& amp;& //忽略脚本和样式节点
!(node.tagName === nodeName.toUpperCase()&&
node.className === className)){//跳过如果已经突出显示
for(var i = 0; i< node.childNodes.length; i ++){
i + = jQuery.highlight(node.childNodes [i],re,nodeName,className,ignoreAccents);
}
}
返回0;
},

removeDiacratics:function(str){
var rExps = [
{re:/ [\xC0- \xC6] / g,ch :'A'},
{re:/ [\xE0- \xE6] / g,ch:'a'},
{re:/ [\xC8-\xCB] / g,ch:'E'},
{re:/ [\xE8-\xEB] / g,ch:'e'},
{re:/ [\xCC- \xCF] / g,ch:'I'},
{re:/ [\xEC-\xEF] / g,ch:'i'},
{re:/ [ \ xD2-\xD6] / g,ch:'O'},
{re:/ [\xF2- \xF6] / g,ch:'o'},
{ re:/ [\xD9-\xDC] / g,ch:'U'},
{re:/ [\xF9- \xFC] / g,ch:'u'},
{re:/ [\xD1] / g,ch:'N'},
{re:/ [\xF1] / g,ch:'n'}
];
for(var i = 0,len = rExps.length; i< len; i ++){
str = str.replace(rExps [i] .re,rExps [i] .ch);
}
return str;
}

});

jQuery.fn.unhighlight = function(options){
var settings = {className:'highlight',element:'span'};
jQuery.extend(设置,选项);

return this.find(settings.element +。+ settings.className).each(
function(){
var parent = this.parentNode;
parent.replaceChild(this.firstChild,this);
parent.normalize();
})。end();
};

jQuery.fn.highlight = function(words,options){
var settings = {className:'highlight',element:'span',caseSensitive:false,wordsOnly:false,ignoreAccents :true};
jQuery.extend(设置,选项);

if(words.constructor === String){
words = [words];
}
words = jQuery.grep(words,function(word,i){
return word!='';
});
words = jQuery.map(words,function(word,i){
return word.replace(/ [ - [\] {}()* +?。,\\ ^ $ |#\s] / g,\\ $&);
});
if(words.length == 0){
return this;
}

var flag = settings.caseSensitive? : 一世;
var pattern =(+ words.join(|)+);
if(settings.wordsOnly){
pattern =\\b+ pattern +\\b;
}

var re = [];
re.push(new RegExp(pattern,flag));

if(settings.ignoreAccents){
var wordsNoAccents = jQuery.map(words,function(word,i){
return jQuery.removeDiacratics(word);
});
var patternNoAccents;
if(settings.wordsOnly){
//使用\\
$分隔字词的解决方法patternNoAccents =(+ wordsNoAccents.join(|)+);
patternNoAccents =\\b+ patternNoAccents +\\b;
} else {
patternNoAccents =(+ wordsNoAccents.join(|)+);

if(patternNoAccents!= pattern){
re.push(new RegExp(patternNoAccents,flag));



return this.each(function(){
for(var i in re){
jQuery.highlight(this,re [i],settings.element,settings.className,settings.ignoreAccents);
}
});
};

(c)jquery.highlight.js javascript ends here



其他注意事项/注意事项从此处开始

1)是我的意图加强,而不是离开,我已经使用的JavaScript,使用户在字段中输入一个单词或短语,只查看包含输入的单词或短语的表行,因为我已经使用的JavaScript正在工作除了上述问题之外(感谢Beetroot对我之前发布的问题的出色贡献)。

2)这涉及我试图实现的功能包括以下4个示例(请注意,因为stackoverflow不允许我在问题中使用多个链接,所以我用[http:// here ]在下面的例子中):

a) [http:// here] demopill.com/jquery-onpage-text-highlighter -and-filter.html [非常类似于我尝试存档的功能;似乎在用户将文本输入到输入字段时成功筛选并突出显示;成功地忽略了大小写,但没有成功忽略重音(例如,é,ñ,ü)];

b) [http:// here] stackoverflow.com/search?q=jquery.highlight.js(stackoverflow上的对话re:忽略重音字符)



c) [http:// here] www.jquery.info/The-plugin-SearchHighlight特征);和

d) [http:// here] docs.jquery.com/UI/Effects/Highlight(包含高亮功能;备注我已在本问题摘要第2段引用的网站上使用jquery ui)。



其他笔记/注意事项在此处结束

突出显示



在页面上安装 jquery.highlight.js ...



更改:

  $ group.find(。filter-count-tr) .text((+ $ s.show()。length +)); 

到:

  $ group.find(。filter-count-tr)。text((+ $ s.show()。unhighlight()。highlight(val).length +)); 

然而,下面的不区分重音代码修改了这个。



Accent Insensitivity



这似乎几乎是不可能的,但我在寻找这个表示 hightlight 插件可能会被修改为提供不区分重音的突出显示。



为了更好地理解代码,我将它重构为一个更好的插件(对我来说更好)。它现在没有将成员放入 jQuery 命名空间(以前是一个),并且一个成员放入 jQuery.fn (之前的两个) 。使用新插件,设置和取消设置亮点的步骤如下:

  $(选择器).highlight('set',words ,选项); 
$(选择器).highlight('unset',options);

代码提供了解释和更多示例(见下文)。 b

'set'设置包括一个'.accentInsensitive'选项,该选项对我实施的有限数量的硬编码(西班牙)重音字符组进行操作(我感到遗憾)插件中的私人成员用于缓存可重复使用的RegExps和替换字符串,供'set'方法稍后使用。有一个广义的Unicode规范化解决方案会更好,但这是另一天的事情。

新插件还提供了将部分代码作为单独方法拆分的机会, .makepattern ,其优点是可以在外部使用RegExp-ready模式,在插件外使用,并为它们重新注入提供条件。这个特性允许我们使用插件作为实现另一个目标的资源 - 即重音不敏感的过滤 - 绝对确定使用的RegExp模式(用于突出显示和过滤)是完全相同的。



以下是插件代码:

  / * 
* jQuery highlightIt插件
* by Beetroot-Beetroot
* https://stackoverflow.com/users/1142252/beetroot-beetroot
*
*基于Bartek Szopka的Highlight, 2009
* http://bartaz.github.com/sandbox.js/jquery.highlight.html,
*根据突出显示v3 by Johann Burkard
* http://johannburkard.de /blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
*最重要的变化:
* - 将代码重构为jQuery首选插件模式。
* - 现在调用:
* - $(slector).highlight('set',words,options);先前的$(slector).highlight(单词,选项);
* - $(slector).highlight('unset',options);先前$(slector).unhighlight(选项);
* - $()。highlight('makePattern',words,options);这个新选项返回一个RegExp-ready模式,可以在外部使用和/或重新注入以供重用(请参阅下面的.isPattern选项),从而避免重新构造可能发生的模式。
* - 'set'.isPattern选项;如果为true,则此新选项表示'words'参数是准备好的RegExp就绪模式。
* - 'set'.accentInsensitive option;这个新选项仅限于硬编码字符组(例如,西班牙语重音字符),而不是Unicode规范化(这将是一种更好的方法,但难以实现并且可能更慢)。
*
*用法:
* //在内容
* //中用< span class ='highlight'>来包装文字'lorem' (默认选项)
* $('#content')。highlight('set','lorem');
*
* //一次搜索并突出显示更多条款
* //这样您可以节省一些时间来遍历DOM
* $('#content')。highlight (['set','lorem','ipsum']);
* $('#content')。highlight('set','lorem ipsum');
*
* //只搜索整个单词'lorem'
* $('#content')。highlight('set','lorem',{wordsOnly:true});
*
* //在搜索术语'lorem'
* $('#content')时不会忽略大小写。 true});
*
* //将内容
* //中的每个术语'ipsum'包含在< em class ='important'>
* $('#content')。highlight('set','ipsum',{element:'em',className:'important'});
*
* //删除默认高亮
* $('#content')。highlight('unset');
*
* //删除自定义高亮
* $('#content')。highlight('unset',{element:'em',className:'important'});
*
* //获得不区分重音的模式
* $()。highlight('makePattern',{element:'lorem',{'accentInsensitive':true});
*
*
*版权所有(c)2009 Bartek Szopka
*
*根据MIT许可证授权。
*
* /

(function($){
// ******************* ***************
// *****开始:私人会员*****
var pluginName ='highlight';
var accentedForms = [//西班牙语加密字符
//原型...
// ['(c |ç)','[cç]','[CÇ]',新的RegExp(' (c |ç)','g'),new RegExp('(C |Ç)','g')],
['(a |á)','[aá]'],
['(e |é)','[eé]'],
['(i |í)','[ií]'],
['(n |ñ) ','[nñ]'],
['(o |ó)','[oó]'],
['(u |ü|ü)','[uúü]']
];
//每次调用set方法时,为了节省大量的硬编码和大量不必要的重复,现在将accentedForms的每一行都转换为原型行的格式,从而提供可重用的RegExps和相应的替换字符串
//注意区分大小写在后面的'set'中因此我们在这里为大写和小写分别准备RegExps。
$ .each(accentedForms,function(i,af){
af [2] = af [1] .toUpperCase();
af [3] = new RegExp(af [0],'g');
af [4] = new RegExp(af [0] .toUpperCase(),'g');
});
var h = function(node,re,settings){
if(node.nodeType === 3){//文本节点
var match = node.data.match(re) ;
if(match){
var wordNode = node.splitText(match.index);
wordNode.splitText(match [0] .length);
$(wordNode).wrap($(<+ settings.element +>)。addClass(s​​ettings.className));
返回1; $(b
$ b)else if((node.nodeType === 1&& node.childNodes)&&&& //只有子元素节点
!/(script |样式)/i.test(node.tagName)&&&& //忽略脚本和样式节点
!(node.tagName === settings.element.toUpperCase()&& node.className == = settings.className)){//跳过如果已经突出显示
for(var i = 0; i< node.childNodes.length; i ++){
i + = h(node.childNodes [i] ,重新设置);
}
}
返回0;
};
// ***** Fin:私人会员*****
// ************************ ********

// ******************************** *
// *****开始:公共方法*****
var methods = {
//这是一种实用程序方法。它返回一个字符串,而不是jQuery。
makePattern:function(words,options){
var settings = {
'accentInsensitive':false
};
$ .extend(settings,options || {});
if(words.constructor === String){
words = [words];
}
words = $ .grep(words,function(word,i){
return word!='';
});
words = $ .map(words,function(word,i){
return word.replace(/ [ - [\] {}()* +?。,\\ ^ $ |#\s] / g,\\ $&);
});
if(words.length == 0){return''; };
var pattern =(+ words.join(|)+);
if(settings.accentInsensitive){
$ .each(accentedForms,function(i,af){
pattern = pattern.replace(af [3],af [1])。replace (af [4],af [2]);
});
}
返回模式;
},
set:function(words,options){
var settings = {$ b $'className':'highlight',$ b $'element':'span' ,
'caseSensitive':false,
'wordsOnly':false,
'accentInsensitive':false,
'isPattern':false
};
$ .extend(settings,options || {});

var pattern = settings.isPattern? words:methods.makePattern(words,settings);
if(pattern ===''){return this; };
if(settings.wordsOnly){
pattern =\\b+ pattern +\\b;
}
var flag = settings.caseSensitive? : 一世;
var re = new RegExp(pattern,flag);
return this.each(function(){
h(this,re,settings);
});
},
unset:function(options){
var settings = {
className:'highlight',
element:'span'
},父母;
$ .extend(settings,options || {});
return this.find(settings.element +。+ settings.className).each(function(){
parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
})。end();
}
};
// ***** Fin:公共方法*****
// ************************ *******

// *****************************
// ***** Start:Supervisor *****
$ .fn [pluginName] = function(method){
if(methods [method]){
return methods [方法] .apply(this,Array.prototype.slice.call(arguments,1));
} else if(typeof method ==='object'||!method){
return methods.init.apply(this,arguments);
} else {
$ .error('Method'+ method +'在jQuery中不存在。'+ pluginName);
}
};
// ***** Fin:主管*****
// ************************* **
})(jQuery);

以下是语言网站的应用程序代码:


$ b $ ('keyup',function(e){
var disallow()。$ b pre $ $(function(){
$(。text-input =(37,38,39,40]; //忽略箭头键
if($。inArray(e.which,disallow)> -1){
return true;
}
var $ group = $(this).closest(。group),
accent_sensitive = false,
case_sensitive = false,
val = this.value,$ b $ ('makePattern',val,{
'accentInsensitive':!accent_sensitive,$ b $'caseSensitive':case_sensitive
}),
$ trs = $ group.find(。myTable tbody tr),
$ s;
if(val ===''){
$ s = $ trs;
}
else {
$ s = $();
$ trs.stop(true,true).each(function(i,tr) {
$ tr = $(tr);
// if($ tr.text()。match(new RegExp(pattern,i))){
if($ tr.text()。match(new RegExp(pattern,case_sensitive ?'':i))){
$ s = $ s.add(tr);
}
});
$ trs.not($ s).hide();

$ group.find(。filter-count-tr)。text((+ $ s.show()。highlight('unset')。highlight('set',模式,{
'isPattern':true,
'caseSensitive':case_sensitive
})。length +)); (this.defaultValue == this.value)this.value ='';
else if(this.value
})。on('focus blur',function(){
if =='')this.value = this.defaultValue;
});

$(。group)。each(function(){
$ this = $(this);
$ this.find(。filter-count-tr ).text((+ $ this.find(tbody tr)。length +));
});
});

所有测试过的,如果安装正确,应该可以正常工作。

顺便说一句,我用 此页 作为西班牙语重音字符的来源。


I have multiple vocabulary tables on the same html page.

Above each vocabulary table, I would like to enable users to type a word or phrase in a text input field to view only the table rows that contain the typed string (word or phrase). For example, if you type "good" in the text input field, the table rows that do not contain the string "good" will disappear. This is already working if you go to http://www.amanado.com/idioma-colombiano/, click on "Vocabulario (oficial y de jerga) - palabras y frases comunes" to expand the accordion section, and then type "good" in the text input field below the words "Ingresa palabra o frase en el siguiente campo para filtrar la información de la tabla". After typing "good" into the text input field, all but 7 rows in the vocabulary table should disappear (7 rows remain).

I am having the following 3 issues:

1) I am unable to ignore accents (e.g., é, ñ, ü) in the same way that case is already successfully ignored. For example, if a user enters "que" in the input field, rows that contain "que" and "qué" should not disappear. However, when you type "que", rows that contain "qué" do erroneously disappear. As you can see, if you type "que" into the input field (excluding the quotes), 2 records that contain "que" will remain. And, if you type or paste "qué" into the input field (excluding the quotes), 6 records that contain "qué" will remain.

2) I am trying to use a version of jquery.highlight.js to highlight the string matches in the rows that remain/do not disappear. For an example of how this should look visually, type "que" into the input field where instructed in the 2nd paragraph of this question summary and you will see the string "que" is highlighted in the 2 rows that remain/do not disappear. Note that this is not working correctly because I hardcoded the "que" highlight by inserting the script "$("table td").highlight("que");" into the "head" section of the html page for the purposes of demonstrating that (a) jquery.highlight.js is active/functioning and (b) providing a visual example of how the highlighted text is intended to appear.

3) In addition to the javascript that enables users to enter a word or phrase in a field to view only the table rows that contain the entered word or phrase not successfully ignoring accents (e.g., é, ñ, ü), which is the desired behavior, the jquery.highlight.js script is also not successfully ignoring accents (e.g., é, ñ, ü). For example, type "pues" in the input field where instructed in the 2nd paragraph of this question summary and you will multiple cases of the string "Qué" and "qué" not successfully highlighted in the rows that remain/do not disappear. Remember, I hardcoded the "que" highlight by inserting the script "$("table td").highlight("que");" into the section of the html page, so the strings "que", "qué", "Que" and "Qué" should all be highlighted in the table rows that remain/do not disappear if any of the strings "que", "qué", "Que" or "Qué" are entered into the input field given it is intended that (a) case and (b) accents (e.g., é, ñ, ü) are ignored. It is interesting to note that functionionality to "ignoreAccents" is included in the version of jquery.highlight.js that I am using.

Below are:

(a) the input field as it appears in my html;

(b) the javascript I am using to enable users to enter a word or phrase in a field to view only the table rows that contain the entered word or phrase (for the purpose of brevity, this is referred to below as "filter javascript"); and

(c) the version of jquery.highlight.js javascript I am using to highlight text.

Please note: I am not a software engineer, but I do know how to implement a change if someone tells me what to do specifically (e.g., make this exact change, then make this exact change, then make this exact change). I appreciate any assistance anyone can provide and literal instructions would be especially appreciated. And, It is always my intent to use the least amount of code (e.g., javascript, css, html) to achieve the most.

Additional notes/considerations are included at the bottom of this question summary.

(a) input field starts here

<form class="live-search" action="" method="post">
<p>Ingresa palabra o frase en el siguiente campo para filtrar la información de la tabla</p>
<input class="input-text-tr" type="text" value="Mostrar sólo filas que contengan..." />
<span class="filter-count-tr"></span>
</form>

(a) input field ends here

(b) filter javascript starts here

$(function() {
$(".input-text-tr").on('keyup', function(e) {
var disallow = [37, 38, 39, 40];//ignore arrow keys    
if($.inArray(e.which, disallow) > -1) {
return true;
}
var inputField = this,
val = this.value,
pattern = new RegExp(val, "i"),
$group = $(this).closest(".group"),
$trs = $group.find(".myTable tbody tr"),
$s;
if(val === '') {
$s = $trs;
}
else {
$s = $();
$trs.stop(true,true).each(function(i, tr) {
if(val !== inputField.value) {//if user has made another     keystroke
return false;//break out of .each() and     hence out of the     event handler
}
$tr = $(tr);
if ($tr.text().match(pattern)) {
$s = $s.add(tr);
}
});
//$trs.not($s).fadeOut();
$trs.not($s).hide();
}
$group.find(".filter-count-tr").text("(" + $s.show        ().length + ")");
}).on('focus blur', function() {
if (this.defaultValue == this.value) this.value = '';
else if (this.value == '') this.value = this.defaultValue;
});

$(".group").each(function() {
$this = $(this);
$this.find(".filter-count-tr").text("(" + $this.find("tbody     tr").length + ")");
});
});

(b) filter javascript ends here

(c) jquery.highlight.js javascript starts here

jQuery.extend({
highlight: function (node, re, nodeName, className,     ignoreAccents) {
if (node.nodeType === 3) {

var nodeData = node.data;
if (ignoreAccents) {
nodeData = jQuery.removeDiacratics(nodeData);
}
var match = nodeData.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';    var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);    
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && //     only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() &&
node.className === className)) { // skip if already     highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className, ignoreAccents);
}
}
return 0;
},

removeDiacratics : function(str) {
var rExps = [
{re:/[\xC0-\xC6]/g, ch:'A'},
{re:/[\xE0-\xE6]/g, ch:'a'},
{re:/[\xC8-\xCB]/g, ch:'E'},
{re:/[\xE8-\xEB]/g, ch:'e'},
{re:/[\xCC-\xCF]/g, ch:'I'},
{re:/[\xEC-\xEF]/g, ch:'i'},
{re:/[\xD2-\xD6]/g, ch:'O'},
{re:/[\xF2-\xF6]/g, ch:'o'},
{re:/[\xD9-\xDC]/g, ch:'U'},
{re:/[\xF9-\xFC]/g, ch:'u'},
{re:/[\xD1]/g, ch:'N'},
{re:/[\xF1]/g, ch:'n'}
];
for (var i = 0, len = rExps.length; i < len; i++) {
str = str.replace(rExps[i].re, rExps[i].ch);
}
return str;
}

});

jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);

return this.find(settings.element + "." +     settings.className).each(
function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};

jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span',     caseSensitive: false, wordsOnly: false, ignoreAccents : true };
jQuery.extend(settings, options);

if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i) {
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) {
return this;
}

var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}

var re = [];
re.push(new RegExp(pattern, flag));

if (settings.ignoreAccents) {
var wordsNoAccents = jQuery.map(words, function(word, i) {
return jQuery.removeDiacratics(word);
});
var patternNoAccents;
if (settings.wordsOnly) {
// workaround for word separation using \\b
patternNoAccents = "( " + wordsNoAccents.join("|") + " )";
patternNoAccents = "\\b" + patternNoAccents + "\\b";
} else {
patternNoAccents = "(" + wordsNoAccents.join("|") + ")";
}
if (patternNoAccents!=pattern) {
re.push(new RegExp(patternNoAccents, flag));
}
}

return this.each(function () {
for (var i in re) {
jQuery.highlight(this, re[i], settings.element,     settings.className, settings.ignoreAccents);
}
});
};

(c) jquery.highlight.js javascript ends here

Additional notes/considerations start here

1) It is my intent to enhance, not depart from, the javascript I am already using to enable users to enter a word or phrase in a field to view only the table rows that contain the entered word or phrase because the javascript I am already using is working with the exception of the above issues (thanks to Beetroot's excellent contributions to a previous question I published).

2) javascript I've found that touches on the functionality I am trying to achieve includes the following 4 examples (note because stackoverflow does not allow me to use more than a couple links in a question, I replaced "http://" with "[http:// here]" in the below examples):

a) [http:// here]demopill.com/jquery-onpage-text-highlighter-and-filter.html [most closely resembles functionality I am trying to achive; seems to successfully filter and highlight as a user enters text into an input field; successfully ignores case, but does not successfully ignore accents (e.g., é, ñ, ü)];

b) [http:// here]stackoverflow.com/search?q=jquery.highlight.js (dialogue on stackoverflow re: ignoring accented characters)

c) [http:// here]www.jquery.info/The-plugin-SearchHighlight (includes a highlight feature); and

d) [http:// here]docs.jquery.com/UI/Effects/Highlight (includes a highlight feature; note that I am already using "jquery ui" on the website referenced in paragraph 2 of this question summary).

Additional notes/considerations end here

解决方案

Highlighting

With jquery.highlight.js installed on the page ...

change :

$group.find(".filter-count-tr").text("(" + $s.show().length + ")");

to :

$group.find(".filter-count-tr").text("(" + $s.show().unhighlight().highlight(val).length + ")");

However, the accent-insensitivity code below modifies this.

Accent Insensitivity

This seemed almost impossible but I had a breakthrough on finding this which indicates how the hightlight plugin might be modified to offer accent-insensitive highlighting.

To better understand the code, I refactored it into a better plugin (better for me anyway). It now puts no members into the jQuery namespace (previously one) and one member into jQuery.fn (previously two). With the new plugin, setting and unsetting highlights is performed as follows:

$(selector).highlight('set', words, options);
$(selector).highlight('unset', options);

Explanations and further examples are provided with the code (see below).

The 'set' settings include an '.accentInsensitive' option, which operates (I regret) on a limited number of hard-coded (Spanish) accented character groups implemented about as efficiently as I can manage using a private member in the plugin to cache reusable RegExps and replacement strings for later use by the 'set' method. It would be far better to have a generalized "Unicode normalisation" solution but that's something for another day.

The new plugin also afforded the opportunity to split out part of the code as a separate method, .makepattern, with the advantage that RegExp-ready patterns can be used externally, outside the plugin, with provision for them to be reinjected. This feature allows us to use the plugin as a resource for achieving the other aim here - namely accent-insensitive filtering - with absolute certainty that the RegExp patterns used (for highlighting and filtering) are identical.

Here's the plugin code :

/*
 * jQuery highlightIt plugin
 * by Beetroot-Beetroot
 * https://stackoverflow.com/users/1142252/beetroot-beetroot
 *
 * based on Highlight by Bartek Szopka, 2009
 * http://bartaz.github.com/sandbox.js/jquery.highlight.html,
 * based on highlight v3 by Johann Burkard
 * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
 *
 * Most important changes:
 * - Code refactored into jQuery preferred plugin pattern.
 * - Now called with : 
 *    - $(slector).highlight('set', words, options); previously $(slector).highlight(words, options);
 *    - $(slector).highlight('unset', options); previously $(slector).unhighlight(options);
 *    - $().highlight('makePattern', words, options); This new option returns a RegExp-ready pattern that can be used externally and/or re-injected for reuse (see .isPattern option below), thus avoiding remaking the pattern as might otherwise happen.
 *  - 'set' .isPattern option; When true, this new option indicates that the 'words' parameter is a prepared RegExp-ready pattern.
 *  - 'set' .accentInsensitive option; This new option is limited to operating on hard-coded character groups (eg, Spanish accented chars), not Unicode normalized (which would be a better approach but much harder to achieve and probably slower).
 *
 * Usage:
 *   // wrap every occurrance of text 'lorem' in content
 *   // with <span class='highlight'> (default options)
 *   $('#content').highlight('set', 'lorem');
 *
 *   // search for and highlight more terms at once
 *   // so you can save some time on traversing DOM
 *   $('#content').highlight(['set', 'lorem', 'ipsum']);
 *   $('#content').highlight('set', 'lorem ipsum');
 *
 *   // search only for entire word 'lorem'
 *   $('#content').highlight('set', 'lorem', { wordsOnly: true });
 *
 *   // don't ignore case during search of term 'lorem'
 *   $('#content').highlight('set', 'lorem', { caseSensitive: true });
 *
 *   // wrap every occurrance of term 'ipsum' in content
 *   // with <em class='important'>
 *   $('#content').highlight('set', 'ipsum', { element: 'em', className: 'important' });
 *
 *   // remove default highlight
 *   $('#content').highlight('unset');
 *
 *   // remove custom highlight
 *   $('#content').highlight('unset', { element: 'em', className: 'important' });
 *
 *   // get accent-insensitive pattern
 *   $().highlight('makePattern', { element: 'lorem', {'accentInsensitive':true});
 *
 *
 * Copyright (c) 2009 Bartek Szopka
 *
 * Licensed under MIT license.
 *
 */

(function($) {
    // **********************************
    // ***** Start: Private Members *****
    var pluginName = 'highlight';
    var accentedForms = [//Spanish accednted chars
        //Prototype ...
        //['(c|ç)', '[cç]', '[CÇ]', new RegExp('(c|ç)','g'), new RegExp('(C|Ç)','g')],
        ['(a|á)', '[aá]'],
        ['(e|é)', '[eé]'],
        ['(i|í)', '[ií]'],
        ['(n|ñ)', '[nñ]'],
        ['(o|ó)', '[oó]'],
        ['(u|ú|ü)', '[uúü]']
    ];
    //To save a lot of hard-coding and a lot of unnecessary repetition every time the "set" method is called, each row of accentedForms is now converted to the format of the prototype row, thus providing reusable RegExps and corresponding replacement strings.
    //Note that case-sensitivity is established later in the 'set' settings so we prepare separate RegExps for upper and lower case here.
    $.each(accentedForms, function(i, af) {
        af[2] = af[1].toUpperCase();
        af[3] = new RegExp(af[0], 'g');
        af[4] = new RegExp(af[0].toUpperCase(), 'g');
    });
    var h = function(node, re, settings) {
        if (node.nodeType === 3) {//text node
            var match = node.data.match(re);
            if (match) {
                var wordNode = node.splitText(match.index);
                wordNode.splitText(match[0].length);
                $(wordNode).wrap($("<" + settings.element + ">").addClass(settings.className));
                return 1;
           }
        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                !(node.tagName === settings.element.toUpperCase() && node.className === settings.className)) { // skip if already highlighted
            for (var i = 0; i < node.childNodes.length; i++) {
                i += h(node.childNodes[i], re, settings);
            }
        }
        return 0;
    };
    // ***** Fin: Private Members *****
    // ********************************

    // *********************************
    // ***** Start: Public Methods *****
    var methods = {
        //This is a utility method. It returns a string, not jQuery.
        makePattern: function (words, options) {
            var settings = {
                'accentInsensitive': false
            };
            $.extend(settings, options || {});
            if (words.constructor === String) {
                words = [words];
            }
            words = $.grep(words, function(word, i) {
              return word != '';
            });
            words = $.map(words, function(word, i) {
              return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
            });
            if (words.length == 0) { return ''; };
            var pattern = "(" + words.join("|") + ")";
            if (settings.accentInsensitive) {
                $.each(accentedForms, function(i, af) {
                    pattern = pattern.replace(af[3], af[1]).replace(af[4], af[2]);
                });
            }
            return pattern;
        },
        set: function (words, options) {
            var settings = {
                'className': 'highlight',
                'element': 'span',
                'caseSensitive': false,
                'wordsOnly': false,
                'accentInsensitive': false,
                'isPattern': false
            };
            $.extend(settings, options || {});

            var pattern = settings.isPattern ? words : methods.makePattern(words, settings);
            if (pattern === '') { return this; };
            if (settings.wordsOnly) {
                pattern = "\\b" + pattern + "\\b";
            }
            var flag = settings.caseSensitive ? "" : "i";
            var re = new RegExp(pattern, flag);
            return this.each(function () {
                h(this, re, settings);
            });
        },
        unset: function (options) {
            var settings = {
                className: 'highlight',
                element: 'span'
            }, parent;
            $.extend(settings, options || {});
            return this.find(settings.element + "." + settings.className).each(function () {
                parent = this.parentNode;
                parent.replaceChild(this.firstChild, this);
                parent.normalize();
            }).end();
        }
    };
    // ***** Fin: Public Methods *****
    // *******************************

    // *****************************
    // ***** Start: Supervisor *****
    $.fn[pluginName] = function( method ) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || !method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' + method + ' does not exist in jQuery.' + pluginName );
        }
    };
    // ***** Fin: Supervisor *****
    // ***************************
})( jQuery );

And here's the application code for the language site :

$(function() {
    $(".text-input").on('keyup', function(e) {
        var disallow = [37, 38, 39, 40];//ignore arrow keys
        if($.inArray(e.which, disallow) > -1) {
            return true;
        }
        var $group = $(this).closest(".group"),
            accent_sensitive = false,
            case_sensitive = false,
            val = this.value,
            pattern = $().highlight('makePattern', val, {
                'accentInsensitive': !accent_sensitive,
                'caseSensitive': case_sensitive
            }),
            $trs = $group.find(".myTable tbody tr"),
            $s;
        if(val === '') {
            $s = $trs;
        }
        else {
            $s = $();
            $trs.stop(true,true).each(function(i, tr) {
                $tr = $(tr);
                //if ($tr.text().match(new RegExp(pattern, "i"))) {
                if ($tr.text().match(new RegExp(pattern, case_sensitive ? '' : "i"))) {
                    $s = $s.add(tr);
                }
            });
            $trs.not($s).hide();
        }
        $group.find(".filter-count-tr").text("(" + $s.show().highlight('unset').highlight('set', pattern, {
            'isPattern':true,
            'caseSensitive':case_sensitive
        }).length + ")");
    }).on('focus blur', function() {
        if (this.defaultValue == this.value) this.value = '';
        else if (this.value == '') this.value = this.defaultValue;
    });

    $(".group").each(function() {
        $this = $(this);
        $this.find(".filter-count-tr").text("(" + $this.find("tbody tr").length + ")");
    });
});

All tested, so should work if installed properly.

By the way, I used this page as my source for Spanish accented characters.

这篇关于jquery过滤器脚本不会忽略变音符号,并且不会突出显示字符串匹配,因为用户在文本输入字段中输入过滤器文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆