0

我在同一个 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 filtrar la información de la tabla”字样下方的文本输入字段中。在文本输入字段中输入“good”后,词汇表中除了 7 行之外的所有行都应该消失(剩下 7 行)。

我有以下3个问题:

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

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

3)除了允许用户在字段中输入单词或短语以仅查看包含未成功忽略重音符号(例如,é、ñ、ü)的输入单词或短语的表行的 javascript 之外,这是所需的行为, jquery.highlight.js 脚本也没有成功忽略重音符号(例如,é、ñ、ü)。例如,在此问题摘要第 2 段中指示的输入字段中键入“pues”,您将在保留/不消失的行中成功突出显示字符串“Qué”和“qué”的多个案例。请记住,我通过插入脚本“$("table td").highlight("que");" 对“que”高亮进行了硬编码。进入html页面的部分,所以字符串“que”,“qué”,“Que”和“Qué” 如果在输入字段中输入任何字符串“que”、“qué”、“Que”或“Qué”,则应在保留/不消失的表格行中全部突出显示,因为它旨在 (a) 大小写和(b) 重音符号(例如 é、ñ、ü)被忽略。有趣的是,我正在使用的 jquery.highlight.js 版本中包含“ignoreAccents”的功能。

以下是:

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

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

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

请注意:我不是软件工程师,但如果有人告诉我具体要做什么,我确实知道如何实施更改(例如,进行确切的更改,然后进行确切的更改,然后进行确切的更改)。我感谢任何人可以提供的任何帮助,特别感谢文字说明。而且,我总是打算使用最少的代码(例如,javascript、css、html)来实现最多。

附加说明/注意事项包含在此问题摘要的底部。

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

<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) 输入字段到此结束

(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) 过滤 javascript 到此结束

(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 using 正在解决上述问题(感谢 Beetroot 对我发布的上一个问题的出色贡献)。

2)我发现涉及我想要实现的功能的javascript包括以下4个示例(注意因为stackoverflow不允许我在一个问题中使用多个链接,我将“http://”替换为以下示例中的“[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的对话:忽略重音字符)

c) [http:// here]www.jquery.info/The-plugin-SearchHighlight(包括高亮功能);和

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

附加说明/注意事项到此结束

4

1 回答 1

1

突出显示

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' 选项,它对有限数量的硬编码(西班牙语)重音字符组进行操作(我很遗憾),其效率与我可以使用插件中的私有成员进行缓存一样有效可重用的正则表达式和替换字符串,供“set”方法稍后使用。拥有一个通用的“Unicode 规范化”解决方案会好得多,但那是另一天的事情了。

新插件还提供了将部分代码拆分为单独方法的机会,.makepattern其优点是可以在插件外部使用 RegExp-ready 模式,并可以重新注入它们。此功能允许我们使用插件作为资源来实现此处的另一个目标 - 即重音不敏感过滤 - 绝对确定使用的 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 <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 );

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

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

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

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

于 2012-07-04T22:03:43.030 回答