最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - change text color of matching text from input in javascript - Stack Overflow

programmeradmin0浏览0评论

Here is my code

And I am trying to change the color of any match in the <li> elements that matches the text in the <input> element. So if you type lets say "this is a simple text" the result should look like this:

<input value="this is a simple text" id="term"/> 
<ul id="ul-id" >
    <li id="li-id-1"> hello budy <span style="color:red">this</span> <span style="color:red">is</span> really <span style="color:red">simple</span> stuff </li>
    <li id="li-id-2"> <span style="color:red">this</span> <span style="color:red">is</span> it</li>
    <li id="li-id-3"> there <span style="color:red">is</span> something here</li>
    <li id="li-id-4"> plain <span style="color:red">text</span> file</li>
</ul>

Here is my code

And I am trying to change the color of any match in the <li> elements that matches the text in the <input> element. So if you type lets say "this is a simple text" the result should look like this:

<input value="this is a simple text" id="term"/> 
<ul id="ul-id" >
    <li id="li-id-1"> hello budy <span style="color:red">this</span> <span style="color:red">is</span> really <span style="color:red">simple</span> stuff </li>
    <li id="li-id-2"> <span style="color:red">this</span> <span style="color:red">is</span> it</li>
    <li id="li-id-3"> there <span style="color:red">is</span> something here</li>
    <li id="li-id-4"> plain <span style="color:red">text</span> file</li>
</ul>

Any help would be appreciated.

Thank you.

Share Improve this question edited Jun 18, 2015 at 9:05 user1636522 asked Jun 18, 2015 at 8:44 NassimNassim 2,8762 gold badges41 silver badges40 bronze badges 3
  • 1 that's pretty plicated to expect someone to build it from scratch for you. – dandavis Commented Jun 18, 2015 at 8:46
  • you know you need some JS to do this? – maioman Commented Jun 18, 2015 at 9:02
  • 2 if you can use jQuery jsfiddle/arunpjohny/aq2gk6qk/2 – Arun P Johny Commented Jun 18, 2015 at 9:04
Add a ment  | 

7 Answers 7

Reset to default 3

You can remove the delay function if you like, but this would lead to a performance loss:

// https://stackoverflow./a/9310752/1636522
RegExp.escape = function (text) {
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
};

window.addEventListener('load', function () {
    var wrapper = '<span style="background:yellow">$&</span>';
    var input = document.getElementById('term');
    var list = document.getElementById('ul-id');
    var items = list.getElementsByTagName('li');
    var l = items.length;
    var source = Array.prototype.map.call(
        items, function (li) { return li.textContent; }
    );
    var cmp = function (a, b) {
        return b.length - a.length;
    };
    var delay = function (fn, ms) {
        var id, scope, args;
        return function () {
            scope = this;
            args = arguments;
            id && clearTimeout(id);
            id = setTimeout(function () { 
                fn.apply(scope, args); 
            }, ms);
        };
    };
    term.addEventListener('keyup', delay(function () {
        var i, re, val;
        if (val = this.value.match(/[^ ]+/g)) {
            val = val.sort(cmp).map(RegExp.escape);
            re = new RegExp(val.join('|'), 'g');
            for (i = 0; i < l; i++) {
                items[i].innerHTML = source[i].replace(re, wrapper);
            }
        }
        else {
            for (i = 0; i < l; i++) {
                items[i].textContent = source[i];
            }
        }
    }, 500));
});
<input value="" id="term"/> 
<ul id="ul-id" >
    <li id="li-id-1"> hello budy this is really simple stuff </li>
    <li id="li-id-2"> this is it</li>
    <li id="li-id-3"> there is something here</li>
    <li id="li-id-4"> plain text file</li>
</ul>

Similar topic: https://stackoverflow./a/20427785/1636522.

I don't know if it is possible with only RegEx, but here is a jQuery solution:

$('#term').change(function() {
    var inpArr = $(this).val().split(" ");

    $('#ul-id li').each(function() {
        var liArr = $(this).text().split(" ");
        var txt = "";
        $.each(liArr, function(i, v) {
            if(inpArr.indexOf(v) > -1) {
                txt += "<span class='red'>"+ v +"</span> ";
            } else {
                txt += v + " ";
            }
        });
        $(this).html(txt);
    });
});

span.red {
     color: red; 
}

And the working fiddle: https://jsfiddle/ermk32yc/1/

Plain JS solution

var list = document.querySelector('#ul-id'),
    listItem,
    listItems,
    term = document.querySelector('#term'),
    oldRef = list.innerHTML,
    oldValue;

term.addEventListener('keyup', function () {
    var regExp,
        value = term.value;

    if (oldValue !== value) {
        oldValue = value;
    
        // Reset
        list.innerHTML = oldRef;
    
        if (value.trim() !== '') {
            listItems = list.querySelectorAll('#ul-id li');
            regExp = new RegExp(term.value, 'g');

            // Perform matching
            for (var i = 0; i < listItems.length; i++) {
                listItem = listItems[i];
                listItem.innerHTML = listItem.innerHTML.replace(regExp, function (match) {
                    return '<span class="matched">' + match + '</span>';
                });
            }
        }
    }

}, false);
.matched {
    color: red;
}
<input  id="term"/> 

<ul id="ul-id" >

    <li id="li-id-1"> hello budy this is really simple stuff </li>
    <li id="li-id-2"> this is it</li>
    <li id="li-id-3"> there is something here</li>
    <li id="li-id-4"> plain text file</li>

</ul>

You might do something like this

$('#term').change(function (i) {
    var terms = $('#term').val().split(" ");
    $('#ul-id > li').each(function (i, el) {
        var val = $(el).html().replace(/<[^<]+>/g, ''),
            match;
        terms.forEach(function (term) {
            val = val.replace(new RegExp(term, 'g'),
                '<span style="color:red">' + term + '</span>');
        });
        $(el).html(val);
    });
});

https://jsfiddle/1vm0259x/5/

You can use the below solution if there is no html contents in the li elemnets

if (!RegExp.escape) {
  RegExp.escape = function(value) {
    return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
  };
}

var lis = [].slice.call(document.querySelectorAll('#ul-id li'));
lis.forEach(function(el) {
  el.dataset.text = el.innerHTML;
});

document.querySelector('#term').addEventListener('change', function() {
  var parts = this.value.split(' ').map(function(value) {
    return '\\b' + RegExp.escape(value) + '\\b';
  });
  var regex = new RegExp(parts.join('|'), 'g');

  lis.forEach(function(el) {
    el.innerHTML = el.dataset.text.replace(regex, function(part) {
      return '<span class="highlight">' + part + '</span>'
    })
  });
});
.highlight {
  color: red;
}
<input id="term" />
<ul id="ul-id">
  <li id="li-id-1">hello budy this is really simple stuff</li>
  <li id="li-id-2">this is it</li>
  <li id="li-id-3">there is something here</li>
  <li id="li-id-4">plain text file</li>
</ul>

With jQuery

if (!RegExp.escape) {
  RegExp.escape = function(value) {
    return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
  };
}

$('#term').on('change keyup', function() {
  //$('#ul-id li .highlight').contents().unwrap();//remove previous highlights

  var parts = this.value.split(' ').map(function(value) {
    return '\\b' + RegExp.escape(value) + '\\b';
  });
  var regex = new RegExp(parts.join('|'), 'g');

  $('#ul-id li ').each(function() {
    var text = $(this).text();
    $(this).html(text.replace(regex, function(part) {
      return '<span class="highlight">' + part + '</span>'
    }))
  })
});
.highlight {
  color: red;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="term" />
<ul id="ul-id">
  <li id="li-id-1">hello budy this is really simple stuff</li>
  <li id="li-id-2">this is it</li>
  <li id="li-id-3">there is something here</li>
  <li id="li-id-4">plain text file</li>
</ul>

you can handle blur event or you can copy paste the inner function code to wherever it is required. this is the guide code here you can more explore match function as per your requirement and then can traverse your li elements as shown below.

$('#term).blur(function() {

  $('#ul-id li').foreach(function()
  {
   if($(this).text().match($("#term").text()))
   {
     ///set/change here  color of  li element
      $(this).css('color', 'red');
   }
  }
}
发布评论

评论列表(0)

  1. 暂无评论