【问题标题】:Seach words given in HTML textarea, and highlight them in a string with JavaScript搜索 HTML textarea 中给出的单词,并使用 JavaScript 在字符串中突出显示它们
【发布时间】:2014-12-21 01:27:23
【问题描述】:

我需要在一个字符串中搜索一些给定的关键字,然后突出显示它们(例如用红色字母写它们)。我尝试了许多不同的方法来解决这个问题,但没有结果。我认为最合乎逻辑的方法是用关键字创建一个数组,然后搜索子字符串并将找到的子字符串放在跨度标签之间,但我在这里有一个问题:如果给定的关键字是 aaaaab,字符串 aaab 应该都是红色的。但是在我找到 aaa 子字符串并将它们放在跨度标签之间之后,我无法找到 aab 并突出显示它,同时保持前一个子字符串的颜色,因为如果我在原字符串中搜索并突出显示新关键字,第一个关键字的span标签会丢失,或者如果我在新字符串中搜索,最后两个a将与b 带有一个 span 结束标签。 有什么办法可以做到这一点,例如在搜索关键字时忽略 HTML 标记或其他什么?

【问题讨论】:

    标签: javascript jquery html string highlight


    【解决方案1】:

    您需要创建一个偏移量/长度对数组。例如“foo aaab bar aaa”,你会得到这个数组:

    [
      {offset: 4, length: 3, keyword: "aaa"},
      {offset: 5, length: 3, keyword: "aab"},
      {offset: 12, length: 3, keyword: "aaa"}
    ]
    

    然后你需要遍历这个数组并展平重叠部分,结果是:

    [
      {offset: 4, length: 4, keywords: ["aaa", "aab"]},
      {offset: 12, length: 3, keywords: ["aaa"]}
    ]
    

    有了这个,你就有足够的信息在不同的偏移量和长度上正确放置跨度标签。

    使偏移变平是最困难的部分,这是我的尝试,但我还没有完全测试它。玩the jsfiddle

    function flattenOffsets(xs){
        var out = [];
        var alreadyProcessed = [];
    
        xs.forEach(function(x, i){
            if (alreadyProcessed.indexOf(x) !== -1) {
                return;
            }
    
            var xStart = x.offset, xEnd = x.offset+x.length;
            var fixed = {offset: x.offset, length: x.length, keywords: [x.keyword]};
            var matches = xs.slice(i+1).filter(function(y){
                var yStart = y.offset, yEnd = y.offset+y.length;
    
                var overlapBefore = xStart <= yStart && xEnd <= yEnd && xEnd >= yStart;
                var overlapAfter = yStart <= xStart && yEnd <= xEnd && yEnd >= xStart;
                var contains = yStart >= xStart && yEnd <= xEnd;
                var contained = xStart >= yStart && xEnd <= yEnd;    
    
                return overlapBefore || overlapAfter || contains || contained;
            }).sort(function(a,b){
                return b.offset - a.offset;
            })
            .forEach(function(y){
                fixed.offset = Math.min(x.offset, y.offset);
                fixed.length = Math.max((x.offset + x.length), (y.offset + y.length)) - fixed.offset;
                fixed.keywords.push(y.keyword);
                alreadyProcessed.push(y);
            });
    
            out.push(fixed);
            alreadyProcessed.push(x);
        });
    
        return out;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-15
      • 1970-01-01
      • 2018-10-23
      • 2011-12-20
      • 2021-09-14
      • 2018-12-12
      • 2014-02-15
      • 2015-10-14
      • 2012-05-04
      相关资源
      最近更新 更多