【问题标题】:Full text search in HTML ignoring tags / &HTML 中的全文搜索忽略标签 / &
【发布时间】:2011-08-18 17:09:44
【问题描述】:

我最近看到了很多用于在 HTML 页面中搜索和突出显示术语的库。然而,我看到的每个库都有同样的问题,他们找不到部分包含在 html 标记中的文本和/或他们无法找到用 & 表示的特殊字符。


示例:

<span> This is a test. This is a <b>test</b> too</span>

搜索“a test”会找到第一个实例,但不会找到第二个。


示例b:

<span> Pencils in spanish are called l&aacute;pices</span>

搜索“lápices”或“lapices”将无法产生结果。


有没有办法绕过这些障碍?

提前致谢!

【问题讨论】:

  • 试试mark.js,它有一个选项acrossElements

标签: javascript html tags full-text-search highlight


【解决方案1】:

这里有两个问题。一个是嵌套内容问题,或跨越元素边界的搜索匹配。另一种是 HTML 转义字符。

处理 HTML 转义字符的一种方法是,例如,如果您使用 jQuery,则使用 .text() 方法,并在其上运行搜索。从中返回的文本已经将转义字符“翻译”成它们的真实字符。

处理这些特殊字符的另一种方法是将实际字符(在搜索字符串中)替换为转义版本。但是,由于存在多种可能性,因此根据实现的不同,这可能是一个冗长的搜索。

可以使用同一种“文本”方法来查找跨越实体边界的内容匹配项。它变得更加棘手,因为“文本”没有任何关于内容的实际部分来自何处的概念,但是如果您深入研究,它会为您提供一个较小的域供您搜索。一旦接近,您可以切换到更多的“字符系列”搜索,而不是基于单词的搜索。

我不知道有任何图书馆可以这样做。

【讨论】:

    【解决方案2】:

    你可以在非IE浏览器中使用window.find(),在IE中使用TextRangefindText()方法。这是一个例子:

    http://jsfiddle.net/xeSQb/6/

    不幸的是,在版本 15 中切换到 Blink 渲染引擎之前的 Opera 不支持 window.findTextRange。如果您对此感到担忧,一个相当重量级的替代方案是使用我的Rangy 库的TextRangeCSS class applier 模块的组合,如以下演示中所示:http://rangy.googlecode.com/svn/trunk/demos/textrange.html

    以下代码是对上述小提琴的改进,每次执行新搜索时都取消突出显示以前的搜索结果:

    function doSearch(text,color="yellow") {
        if (color!="transparent") {
          doSearch(document.getElementById('hid_search').value,"transparent"); 
          document.getElementById('hid_search').value = text; 
          }
        if (window.find && window.getSelection) {
            document.designMode = "on";
            var sel = window.getSelection();
            sel.collapse(document.body, 0);
            
            while (window.find(text)) {
                document.execCommand("HiliteColor", false, color);
                sel.collapseToEnd();
            }
            document.designMode = "off";
        } else if (document.body.createTextRange) {
            var textRange = document.body.createTextRange();
            while (textRange.findText(text)) {
                textRange.execCommand("BackColor", false, color);
                textRange.collapse(false);
            }
        }
    }
    <input type="text" id="search">
    <input type="hidden" id="hid_search">
    <input type="button" id="button" onmousedown="doSearch(document.getElementById('search').value)" value="Find">
    
    <div id="content">
        <p>Here is some searchable text with some lápices in it, and more lápices, and some <b>for<i>mat</i>t</b>ing</p>
    </div> 

    【讨论】:

    • 此代码中的一个(非常)小缺陷是它从当前光标位置开始搜索,因此如果用户突出显示一段文本并单击按钮,则搜索在用户突出显示之后开始。理想情况下,在 find() 调用之前应该有某种调用将光标带到顶部。
    • @tim down 如何删除上面代码突出显示的撤消高亮..
    • Opera 既不支持window.find 也不支持createTextRange(也不支持findText 对象上的findText 方法)
    • 一点更新:Opera 15 和更新版本支持 window.find,因为它在 webkit 上。
    • 如何清除突出显示的单词?清除它,让它恢复正常,没有亮点......
    【解决方案3】:

    使用javascript突出显示搜索关键字并从网页中删除突出显示

        <script>
    
    
        function highlightAll(keyWords) { 
            document.getElementById('hid_search_text').value = keyWords; 
            document.designMode = "on"; 
            var sel = window.getSelection(); 
            sel.collapse(document.body, 0);
            while (window.find(keyWords)) { 
                document.execCommand("HiliteColor", false, "yellow"); 
                sel.collapseToEnd(); 
            }
            document.designMode = "off";
            goTop(keyWords,1); 
        }
    
        function removeHighLight() { 
            var keyWords = document.getElementById('hid_search_text').value; 
            document.designMode = "on"; 
            var sel = window.getSelection(); 
            sel.collapse(document.body, 0);
            while (window.find(keyWords)) { 
                document.execCommand("HiliteColor", false, "transparent"); 
                sel.collapseToEnd(); 
            }
            document.designMode = "off"; 
            goTop(keyWords,0); 
        }
    
        function goTop(keyWords,findFirst) { 
            if(window.document.location.href = '#') { 
                if(findFirst) { 
                    window.find(keyWords, 0, 0, 1);
                }
            }
        }
        </script>
    
        <style>
        #search_para {
         color:grey;
        }
        .highlight {
         background-color: #FF6; 
        }
        </style>
    
        <div id="wrapper">
            <input type="text" id="search_text" name="search_text"> &nbsp; 
            <input type="hidden" id="hid_search_text" name="hid_search_text"> 
            <input type="button" value="search" id="search" onclick="highlightAll(document.getElementById('search_text').value)" >  &nbsp; 
            <input type="button" value="remove" id="remove" onclick="removeHighLight()" >  &nbsp; 
            <div>
                <p id="search_para">The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words. Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators. To achieve this, it would be necessary to have uniform grammar, pronunciation and more common words. If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages. The new common language will be more simple and regular than the existing European languages.</p>
            </div>
        </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多