javascript - 正则表达式与javascript中的html标签不匹配

标签 javascript jquery search highlight

Possible Duplicate:
highlight words in html using regex & javascript - almost there

更新 --> 一旦解决,最终的脚本就是:

var regex;
var filterSize;

function normalizar(str) {
    var fin=str.toLowerCase().replace('á','a').replace('é','e').replace('í','i').replace('ó','o').replace('ú','u');

    return fin;
}

function highlight(fin) {
    htmlFin="";
    while ((match = regex.exec(normalizar(fin))) != null) {
        posIni=match.index;
        posEnd = posIni+filterSize;
        var ini="";
        if (posIni != 0) ini=fin.substring(0, posIni);
        var sub=fin.substring(posIni, posEnd);
        fin=fin.substring(posEnd, fin.length);

        htmlFin += ini+"<span class='highlight'>"+sub+"</span>";
    }
    htmlFin += fin;

    return htmlFin;
}

function procesar(elemento) {
    elemento.children().each(function() {
        var mas=$(this).children().size();
        if (mas == 0) {
            $(this).html(highlight($(this).text()));
        } else {
            procesar($(this));
        }
    });
}

$(document).ready(function(){

    $(".filter").keyup(function(){

        // Cogemos el texto de búsqueda
        var filter = $(this).val();
        //Ponemos el contador a 0
        var count = 0;
        $('span.highlight').each(function() {
            $(this).replaceWith($(this).text());
        });

        //Por cada elemento de la lista...
        $(".list tr:not(:first-child)").each(function(){
            var html=$(this).html();
            var posIni = -1;
            var posEnd = -1;

            filterNorm=normalizar(filter);
            filterSize=filter.length;
            regex=new RegExp(filterNorm, 'gi');
            var buscar=normalizar($(this).text()).search(regex);
            var htmlFin="";
            if (buscar > -1) {
                if (filter) procesar($(this));
                $(this).show();
                count++;

            } else $(this).fadeOut();
        });

        // Actualizamos la cuenta
        if (filter) {
            var numberItems = count;
            //Si no hay coincidencias lo mostramos en rojo.
            if (count==0) $(".cuenta").html("<span class='error'>Coincidencias = "+count+"</span>");
            else $(".cuenta").text("Coincidencias: "+count);
            //Si no hay filtro, limpiamos el html de cuentas.
        } else $(".cuenta").text("");
    });
});

目标是使用 jquery/javascript 制作一个搜索脚本,突出显示输入中 a 中的匹配项。它必须忽略大小写和变音符号(重音)符号和 html 标签

我很接近做到这一点,但它失败了,因为它不忽略 html 标签,我的意思是,脚本突出显示 html 标签也匹配......

例如:

更新:您可以在此处尝试该脚本 jsfiddle.net/josecash/nD6dg/2 ,只需输入 td 或 < 或 > 即可查看错误。

假设我有一个这样的表:

<table>
<tr><th>Name</th><th>Kind</th><th>Type</th></tr>
<tr>
<td><strong>Fedora</strong></td>
<td>Linux</td>
<td>Operative System</td>
</tr>
</table>

如果我在输入中键入字母 o,我的脚本将突出显示 Fedora 和 Operating System 中的 o,而且还会突出显示标记 strong。

我想我可以使用正则表达式变量中的正则表达式来做到这一点,但我无法弄清楚......

任何帮助将非常感激

脚本如下所示:

$(document).ready(function(){

    $(".filter").keyup(function(){

        // Input text
        var filter = $(this).val();
        //Ponemos el contador a 0
        var count = 0;
        $('span.highlight').each(function() {
            $(this).replaceWith($(this).text());
        });

        //Foreach tr in the table
        $(".list tr:not(:first-child)").each(function(){
            var html=$(this).html();
            var posIni = -1;
            var posEnd = -1;

                    // normalizar just replace accents
            filterNorm=normalizar(filter);
            var filterSize=filter.length;
            var regex=new RegExp(filterNorm, 'gi');
            var buscar=normalizar($(this).text()).search(regex);
            var htmlFin="";

            if (buscar > -1) {
                if (filter) {
                    var end=html;
                    while ((match = regex.exec(normalizar(end))) != null) {
                        posIni=match.index;
                        posEnd = posIni+filterSize;
                        var ini="";
                        if (posIni != 0) ini=end.substring(0, posIni);

                        var sub=end.substring(posIni, posEnd);
                        end=end.substring(posEnd, end.length);

                        htmlFin += ini+"<span class='highlight'>"+sub+"</span>";
                    }
                    htmlFin += end;
                }
                if (filter) $(this).show().html(htmlFin);
                else $(this).show();
                count++;
            } else $(this).fadeOut();
        });
    });
});

最佳答案

@Josecash,

避免处理 HTML 标记本身的一个好方法是:

  • 使用纯 JavaScript 而不是 jQuery 发现子节点
  • 在遇到文本节点时对其进行处理
  • 在遇到元素节点时进一步深入(递归)。

整体代码如下:

$(document).ready(function(){
    //Highlighter function
    function highlight(text) {
        //Your highlight code here
        //...
        //return text with added HTML markup
    }

    //Recursive scanner function to penetrate the DOM tree.
    function scanNode(index, node) {
        //node is a plain javascript reference to a DOM node, not jQuery-wrapped.
        if(node.nodeType == 3) {//hurray, it's a TEXT_NODE
            $(node).replaceWith(highlight(node.nodeValue));
        }
        else if(node.nodeType == 1){//it's an ELEMENT_NODE
            //Here, for convenience, we use jQuery's utility `.each() method
            //but we are still essentially working in plain javascript.
            $.each(node.childNodes, scanNode);
        }
    }

    var $list = $(".list");
    //master routine
    $(".filter").keyup(function() {
        $list.find('span.highlight').each(function() {
            var $this = $(this);
            $this.replaceWith($this.text());
        }).find("tr:gt(1)").each(scanNode);
    });
});

感谢@Bergi 在下面提供的意见

您必须编写 highlight() 函数,这将是对上面代码的相当简单的修改。确保该函数返回标记的文本字符串。

关键行$(node).replaceWith(highlight(node.nodeValue));已经过测试(在Opera 12.12和IE9中); jsFiddle

其他一切都未经测试,因此可能需要调试。

关于javascript - 正则表达式与javascript中的html标签不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14305202/

相关文章:

javascript - 这个结构可以一直工作吗

algorithm - 八皇后回溯解决方案是否需要任何排序?

javascript - 如何在cheerio中获取div的 child

javascript - 在提交表单之前显示一个 css 弹出窗口

JavaScript - 如何在内容中间插入 HTML 代码

elasticsearch - Elasticsearch搜索结果相关性问题

search - 用 Go 编写的开源搜索

javascript - Puppeteer - page.$$ ('' ).length 返回未定义

jquery - 停止第一个 <li> 的可拖动

javascript - 光滑的 slider 同步 - 断点上的自定义箭头