jqueryfilter脚本不忽略变音符号而不突出显示字符串匹配,因为用户将filter文本输入到文本输入字段中

我在同一个html页面上有多个词汇表。

在每个词汇表上方,我希望用户能够在文本输入字段中键入单词或短语,以仅查看包含键入的字符串(单词或短语)的表行。 例如,如果在文本输入字段中键入“good”,则不包含字符串“good”的表行将消失。 如果你去http://www.amanado.com/idioma-colombiano/ ,点击“Vocabulario(oficial y de jerga) – palabras y frases comunes”扩展手风琴部分,然后输入“good” “在”Ingresa palabra o frase en el siguiente campo para filtrarlainformacióndela tabla“下面的文字输入栏中。 在文本输入字段中键入“good”后,词汇表中除7行外的所有行都将消失(保留7行)。

我有以下3个问题:

1)我无法忽略重音(例如,é,ñ,ü),就像已成功忽略大小写一样。 例如,如果用户在输入字段中输入“que”,则包含“que”和“qué”的行不应消失。 但是,当您键入“que”时,包含“qué”的行会错误地消失。 如您所见,如果在输入字段中键入“que”(不包括引号),则将保留包含“que”的2条记录。 并且,如果您在输入字段中键入或粘贴“qué”(不包括引号),则将保留包含“qué”的6条记录。

2)我正在尝试使用jquery.highlight.js的一个版本来突出显示保持/不消失的行中的字符串匹配。 有关它应如何在视觉上显示的示例,请在此问题摘要的第2段中指示的输入字段中键入“que”,您将看到字符串“que”在保留/不消失的2行中突出显示。 请注意,这不能正常工作,因为我通过插入脚本“$(”table td“)来硬编码”que“突出显示.highlight(”que“);” 进入html页面的“head”部分,目的是为了certificate(a)jquery.highlight.js是活动的/正在运行的,以及(b)提供一个如何突出显示文本的可视化示例。

3)除了允许用户在字段中输入单词或短语的javascript之外,还只查看包含输入的单词或短语的表行,而不是成功忽略重音(例如,é,ñ,ü),这是所需的行为,jquery.highlight.js脚本也没有成功忽略重音(例如,é,ñ,ü)。 例如,在此问题摘要的第2段中指示的输入字段中键入“pues”,您将在保留/不消失的行中未成功突出显示字符串“Qué”和“qué”的多个案例。 记住,我通过插入脚本“$(”table td“)来硬编码”que“突出显示.highlight(”que“);” 进入html页面的部分,所以字符串“que”,“qué”,“Que”和“Qué”都应该在表行中突出显示,如果任何字符串“que”,则不会消失。 qué“,”Que“或”Qué“被输入到输入字段中,因为它意图忽略(a)情况和(b)重音(例如,é,ñ,ü)。 值得注意的是,“ignoreAccents”的function性包含在我正在使用的jquery.highlight.js版本中。

以下是:

(a)我的html中出现的输入字段;

(b)我用来使用户在字段中输入单词或短语以仅查看包含输入的单词或短语的表行的javascript(为了简洁起见,这在下面称为“filterjavascript” ); 和

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

请注意:我不是软件工程师,但如果有人告诉我具体做什么(例如,做出这个确切的更改,然后做出这个确切的更改,然后做出这个确切的更改),我确实知道如何实施更改。 我感谢任何人都能提供的帮助,特别感谢文字指示。 并且,我总是希望使用最少量的代码(例如,javascript,css,html)来实现最大化。

其他说明/注意事项包含在本问题摘要的底部。

(a)输入字段从这里开始

 

(a)输入字段在此结束

(b)过滤javascript从这里开始

 $(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)filterjavascript在这里结束

(c)jquery.highlight.js javascript从这里开始

 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在这里结束

其他说明/注意事项从这里开始

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

2) javascript我发现触及我试图实现的function包括以下4个示例(注意因为stackoverflow不允许我在一个问题中使用多个链接,我用“http://”代替“[http:// here]”在以下示例中:

a) [http:// here] demopill.com/jquery-onpage-text-highlighter-and-filter.html [最接近我试图实现的function; 当用户将文本输入到输入字段时,似乎成功过滤和突出显示; 成功忽略大小写,但没有成功忽略重音(例如,é,ñ,ü)];

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

c) [http:// here] www.jquery.info/The-plugin-SearchHighlight(包括突出显示function); 和

d) [http:// here] docs.jquery.com/UI/Effects/Highlight(包括一个突出显示的function;请注意我已在本问题摘要第2段中引用的网站上使用“jquery ui”)。

其他说明/注意事项在此结束

突出

jquery.highlight.js安装了jquery.highlight.js

改变:

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

至 :

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

但是,下面的重音不敏感代码会修改它。

口音不敏感

这似乎几乎不可能,但我找到了一个突破,表明如何修改hightlight插件,以提供重音不敏感的突出显示。

为了更好地理解代码,我将它重构为一个更好的插件(无论如何我都更好)。 它现在没有成员进入jQuery名称空间(以前的一个)和一个成员到jQuery.fn (以前的两个)。 使用新插件,设置和取消设置高亮显示如下:

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

代码提供了解释和进一步的示例(见下文)。

‘set’设置包括一个’.accentInsensitive’选项,它对有限数量的硬编码(西class牙语)重音字符组进行操作(我很遗憾)实现的效率与我可以使用插件中的私有成员进行管理一样高效可重复使用的RegExps和替换字符串,供以后使用’set’方法使用。 拥有一个通用的“Unicode规范化”解决方案会好得多,但那是另一天的事情。

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

这是插件代码:

 /* * 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  (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  * $('#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 ); 

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

 $(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 + ")"); }); }); 

所有测试,如果安装正确应该工作。

顺便说一句,我用这个页面作为西class牙语重音字符的来源。