JQuery:如何在一个范围内包装给定的文本部分?

问题描述 投票:0回答:2

我有一系列标题元素,其中包含文本和文本输入。当我将一个字符串放入文本输入中时,我想突出显示(用

<span>
包装)标题元素中的响应字符。

例如,如果文本输入包含单词“world”,那么我希望将同一个单词包裹在高光范围内,例如

<div class="title">Hello <span class="highlight">World</span>! This is a title</div>

我已经通过

.replace()
实现了这一点,例如:

// value is .val recieved from input
function highlight(value) {
    $('.title').each(function() {
        var original = $(this).text();
        var newText = original.replace(value, "<span class='highlight'>" + value + "</span>");
        $(this).html(newText);
    });
};

但是,这有几个限制:

  1. 它不适用于大写(如果用户输入

    world
    字符串
    World
    将不会突出显示)。

  2. 它只适用于单词的第一个实例(如果字符串中有多个单词

    world
    的实例,它只会突出第一个。

我试图通过获取每个输入字符串的开始和结束位置来插入

<span>
s来解决这个问题,但这只是造成了混乱:

function highlight(value, el) {
    $(el).each(function() {
        var original = $(this).text();
        var startPosition = original.indexOf(value);
        
        if (startPosition !== 0 || startPosition !== -1) {
            var endPosition = (startPosition + value.length);
                            
           var newString = original.slice(0, startPosition)
            + '<span class="highlight">'
            + original.slice(startPosition, endPosition)
            + '</span>'
            + original.slice(startPosition);
            
            $(this).html(newString);
        }
    });
};

有人知道这是否可行吗?谁能指出我正确的方向?

(PS:如果可能我宁愿不使用插件)

javascript jquery indexof
2个回答
2
投票

您可以使用正则表达式

仅抓取包含该词的标题不会有太大收获,因为那也会循环

function highlight(value) {
  $('.title').each(function() {
    var original = $(this).text();
    const text = original.match(new RegExp(value, 'i'));
    if (text) { // null if not found
      var newText = original.replace(text, "<span class='highlight'>" + text[0] + "</span>");
      $(this).html(newText);
    }
  });
};
highlight("world")
span {
  color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="title">Hello world</h1>
<h1 class="title">Hello World</h1>


1
投票

对于被接受的答案,如果字符串包含多个匹配的子串,则不会高亮显示

function highlight(value) {
    const pattern = '\\b' + value + '\\b';
    $('.title').each(function () {
        var original = $(this).text();
        const text = original.match(new RegExp(pattern, 'gi'));
        if (text && text.length) { // null if not found
            text.map(item => {
                original = original.replace(item, "<span class='highlight'>" + item + "</span>");
                $(this).html(original);
            })
        }
    });
};
highlight("wor");
span {
  color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="title">World Hello world WorLD</h1>
<h1 class="title">Hello World</h1>

© www.soinside.com 2019 - 2024. All rights reserved.